From 9c7dc9cb4baec9d8dea837f6fa5ebc8dc76ea3cd Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 11 Oct 2018 11:43:07 -0500 Subject: [PATCH 1/3] Refactor CpuMathUtils - Allow it to take Spans instead of arrays. - Remove redundant overloads - When multiple spans are accepted, always use an explicit count parameter instead of one being chosen as having the right length. Working towards #608 --- src/Microsoft.ML.Core/Utilities/Contracts.cs | 13 + src/Microsoft.ML.CpuMath/AvxIntrinsics.cs | 62 +-- .../CpuMathUtils.netcoreapp.cs | 388 +++--------------- .../CpuMathUtils.netstandard.cs | 69 ++-- .../Microsoft.ML.CpuMath.csproj | 1 + src/Microsoft.ML.CpuMath/Sse.cs | 323 ++++----------- src/Microsoft.ML.CpuMath/SseIntrinsics.cs | 64 +-- .../Depricated/Vector/VBufferMathUtils.cs | 16 +- .../Depricated/Vector/VectorUtils.cs | 18 +- .../Standard/LinearClassificationTrainer.cs | 4 +- .../Standard/SdcaMultiClass.cs | 8 +- src/Microsoft.ML.Transforms/GcnTransform.cs | 18 +- .../WhiteningTransform.cs | 2 +- .../BenchmarksTest.cs | 2 +- .../AvxPerformanceTests.cs | 25 +- .../SsePerformanceTests.cs | 25 +- .../UnitTests.cs | 22 +- 17 files changed, 320 insertions(+), 740 deletions(-) diff --git a/src/Microsoft.ML.Core/Utilities/Contracts.cs b/src/Microsoft.ML.Core/Utilities/Contracts.cs index 89c18b3bd4..eb371bfff3 100644 --- a/src/Microsoft.ML.Core/Utilities/Contracts.cs +++ b/src/Microsoft.ML.Core/Utilities/Contracts.cs @@ -945,6 +945,19 @@ public static void AssertNonWhiteSpace(this IExceptionContext ctx, string s, str DbgFailEmpty(ctx, msg); } + [Conditional("DEBUG")] + public static void AssertNonEmpty(ReadOnlySpan args) + { + if (args.IsEmpty) + DbgFail(); + } + [Conditional("DEBUG")] + public static void AssertNonEmpty(Span args) + { + if (args.IsEmpty) + DbgFail(); + } + [Conditional("DEBUG")] public static void AssertNonEmpty(ICollection args) { diff --git a/src/Microsoft.ML.CpuMath/AvxIntrinsics.cs b/src/Microsoft.ML.CpuMath/AvxIntrinsics.cs index 0d2c015fa3..2947c4a961 100644 --- a/src/Microsoft.ML.CpuMath/AvxIntrinsics.cs +++ b/src/Microsoft.ML.CpuMath/AvxIntrinsics.cs @@ -606,12 +606,12 @@ public static unsafe void Scale(float scale, Span dst) } } - public static unsafe void ScaleSrcU(float scale, Span src, Span dst) + public static unsafe void ScaleSrcU(float scale, ReadOnlySpan src, Span dst, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) { - float* pDstEnd = pdst + dst.Length; + float* pDstEnd = pdst + count; float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -697,14 +697,14 @@ public static unsafe void ScaleAddU(float a, float b, Span dst) } } - public static unsafe void AddScaleU(float scale, Span src, Span dst) + public static unsafe void AddScaleU(float scale, ReadOnlySpan src, Span dst, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; - float* pEnd = pdst + dst.Length; + float* pEnd = pdst + count; Vector256 scaleVector256 = Avx.SetAllVector256(scale); @@ -751,13 +751,13 @@ public static unsafe void AddScaleU(float scale, Span src, Span ds } } - public static unsafe void AddScaleCopyU(float scale, Span src, Span dst, Span result) + public static unsafe void AddScaleCopyU(float scale, ReadOnlySpan src, ReadOnlySpan dst, Span result, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) fixed (float* pres = result) { - float* pResEnd = pres + result.Length; + float* pResEnd = pres + count; float* pSrcCurrent = psrc; float* pDstCurrent = pdst; float* pResCurrent = pres; @@ -807,7 +807,7 @@ public static unsafe void AddScaleCopyU(float scale, Span src, Span src, Span idx, Span dst) + public static unsafe void AddScaleSU(float scale, ReadOnlySpan src, ReadOnlySpan idx, Span dst, int count) { fixed (float* psrc = src) fixed (int* pidx = idx) @@ -816,7 +816,7 @@ public static unsafe void AddScaleSU(float scale, Span src, Span idx float* pSrcCurrent = psrc; int* pIdxCurrent = pidx; float* pDstCurrent = pdst; - int* pEnd = pidx + idx.Length; + int* pEnd = pidx + count; Vector256 scaleVector256 = Avx.SetAllVector256(scale); @@ -858,14 +858,14 @@ public static unsafe void AddScaleSU(float scale, Span src, Span idx } } - public static unsafe void AddU(Span src, Span dst) + public static unsafe void AddU(ReadOnlySpan src, Span dst, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; - float* pEnd = psrc + src.Length; + float* pEnd = psrc + count; while (pSrcCurrent + 8 <= pEnd) { @@ -905,7 +905,7 @@ public static unsafe void AddU(Span src, Span dst) } } - public static unsafe void AddSU(Span src, Span idx, Span dst) + public static unsafe void AddSU(ReadOnlySpan src, ReadOnlySpan idx, Span dst, int count) { fixed (float* psrc = src) fixed (int* pidx = idx) @@ -914,7 +914,7 @@ public static unsafe void AddSU(Span src, Span idx, Span dst) float* pSrcCurrent = psrc; int* pIdxCurrent = pidx; float* pDstCurrent = pdst; - int* pEnd = pidx + idx.Length; + int* pEnd = pidx + count; while (pIdxCurrent + 8 <= pEnd) { @@ -950,7 +950,7 @@ public static unsafe void AddSU(Span src, Span idx, Span dst) } } - public static unsafe void MulElementWiseU(Span src1, Span src2, Span dst) + public static unsafe void MulElementWiseU(ReadOnlySpan src1, ReadOnlySpan src2, Span dst, int count) { fixed (float* psrc1 = src1) fixed (float* psrc2 = src2) @@ -959,7 +959,7 @@ public static unsafe void MulElementWiseU(Span src1, Span src2, Sp float* pSrc1Current = psrc1; float* pSrc2Current = psrc2; float* pDstCurrent = pdst; - float* pEnd = pdst + dst.Length; + float* pEnd = pdst + count; while (pDstCurrent + 8 <= pEnd) { @@ -999,7 +999,7 @@ public static unsafe void MulElementWiseU(Span src1, Span src2, Sp } } - public static unsafe float SumU(Span src) + public static unsafe float SumU(ReadOnlySpan src) { fixed (float* psrc = src) { @@ -1037,7 +1037,7 @@ public static unsafe float SumU(Span src) } } - public static unsafe float SumSqU(Span src) + public static unsafe float SumSqU(ReadOnlySpan src) { fixed (float* psrc = src) { @@ -1081,7 +1081,7 @@ public static unsafe float SumSqU(Span src) } } - public static unsafe float SumSqDiffU(float mean, Span src) + public static unsafe float SumSqDiffU(float mean, ReadOnlySpan src) { fixed (float* psrc = src) { @@ -1130,7 +1130,7 @@ public static unsafe float SumSqDiffU(float mean, Span src) } } - public static unsafe float SumAbsU(Span src) + public static unsafe float SumAbsU(ReadOnlySpan src) { fixed (float* psrc = src) { @@ -1174,7 +1174,7 @@ public static unsafe float SumAbsU(Span src) } } - public static unsafe float SumAbsDiffU(float mean, Span src) + public static unsafe float SumAbsDiffU(float mean, ReadOnlySpan src) { fixed (float* psrc = src) { @@ -1223,7 +1223,7 @@ public static unsafe float SumAbsDiffU(float mean, Span src) } } - public static unsafe float MaxAbsU(Span src) + public static unsafe float MaxAbsU(ReadOnlySpan src) { fixed (float* psrc = src) { @@ -1267,7 +1267,7 @@ public static unsafe float MaxAbsU(Span src) } } - public static unsafe float MaxAbsDiffU(float mean, Span src) + public static unsafe float MaxAbsDiffU(float mean, ReadOnlySpan src) { fixed (float* psrc = src) { @@ -1316,14 +1316,14 @@ public static unsafe float MaxAbsDiffU(float mean, Span src) } } - public static unsafe float DotU(Span src, Span dst) + public static unsafe float DotU(ReadOnlySpan src, ReadOnlySpan dst, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; - float* pSrcEnd = psrc + src.Length; + float* pSrcEnd = psrc + count; Vector256 result256 = Avx.SetZeroVector256(); @@ -1371,7 +1371,7 @@ public static unsafe float DotU(Span src, Span dst) } } - public static unsafe float DotSU(Span src, Span dst, Span idx) + public static unsafe float DotSU(ReadOnlySpan src, ReadOnlySpan dst, ReadOnlySpan idx, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) @@ -1380,7 +1380,7 @@ public static unsafe float DotSU(Span src, Span dst, Span idx float* pSrcCurrent = psrc; float* pDstCurrent = pdst; int* pIdxCurrent = pidx; - int* pIdxEnd = pidx + idx.Length; + int* pIdxEnd = pidx + count; Vector256 result256 = Avx.SetZeroVector256(); @@ -1428,14 +1428,14 @@ public static unsafe float DotSU(Span src, Span dst, Span idx } } - public static unsafe float Dist2(Span src, Span dst) + public static unsafe float Dist2(ReadOnlySpan src, ReadOnlySpan dst, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; - float* pSrcEnd = psrc + src.Length; + float* pSrcEnd = psrc + count; Vector256 sqDistanceVector256 = Avx.SetZeroVector256(); @@ -1482,13 +1482,13 @@ public static unsafe float Dist2(Span src, Span dst) } } - public static unsafe void SdcaL1UpdateU(float primalUpdate, Span src, float threshold, Span v, Span w) + public static unsafe void SdcaL1UpdateU(float primalUpdate, int count, ReadOnlySpan src, float threshold, Span v, Span w) { fixed (float* psrc = src) fixed (float* pdst1 = v) fixed (float* pdst2 = w) { - float* pSrcEnd = psrc + src.Length; + float* pSrcEnd = psrc + count; float* pSrcCurrent = psrc; float* pDst1Current = pdst1; float* pDst2Current = pdst2; @@ -1544,14 +1544,14 @@ public static unsafe void SdcaL1UpdateU(float primalUpdate, Span src, flo } } - public static unsafe void SdcaL1UpdateSU(float primalUpdate, Span src, Span indices, float threshold, Span v, Span w) + public static unsafe void SdcaL1UpdateSU(float primalUpdate, int count, ReadOnlySpan src, ReadOnlySpan indices, float threshold, Span v, Span w) { fixed (float* psrc = src) fixed (int* pidx = indices) fixed (float* pdst1 = v) fixed (float* pdst2 = w) { - int* pIdxEnd = pidx + indices.Length; + int* pIdxEnd = pidx + count; float* pSrcCurrent = psrc; int* pIdxCurrent = pidx; diff --git a/src/Microsoft.ML.CpuMath/CpuMathUtils.netcoreapp.cs b/src/Microsoft.ML.CpuMath/CpuMathUtils.netcoreapp.cs index 09738684f5..fcbbb35222 100644 --- a/src/Microsoft.ML.CpuMath/CpuMathUtils.netcoreapp.cs +++ b/src/Microsoft.ML.CpuMath/CpuMathUtils.netcoreapp.cs @@ -197,17 +197,10 @@ public static void MatTimesSrc(bool tran, bool add, AlignedArray mat, int[] rgpo } } - public static void Add(float a, float[] dst, int count) + public static void Add(float a, Span dst) { Contracts.AssertNonEmpty(dst); - Contracts.Assert(count > 0); - Contracts.Assert(count <= dst.Length); - - Add(a, new Span(dst, 0, count)); - } - private static void Add(float a, Span dst) - { if (Avx.IsSupported) { AvxIntrinsics.AddScalarU(a, dst); @@ -225,27 +218,10 @@ private static void Add(float a, Span dst) } } - public static void Scale(float a, float[] dst, int count) + public static void Scale(float a, Span dst) { Contracts.AssertNonEmpty(dst); - Contracts.Assert(count > 0); - Contracts.Assert(count <= dst.Length); - - Scale(a, new Span(dst, 0, count)); - } - public static void Scale(float a, float[] dst, int offset, int count) - { - Contracts.AssertNonEmpty(dst); - Contracts.Assert(count > 0); - Contracts.Assert(offset >= 0); - Contracts.Assert(offset < (dst.Length - count)); - - Scale(a, new Span(dst, offset, count)); - } - - private static void Scale(float a, Span dst) - { if (Avx.IsSupported) { AvxIntrinsics.Scale(a, dst); @@ -264,7 +240,7 @@ private static void Scale(float a, Span dst) } // dst = a * src - public static void Scale(float a, float[] src, float[] dst, int count) + public static void Scale(float a, ReadOnlySpan src, Span dst, int count) { Contracts.AssertNonEmpty(src); Contracts.AssertNonEmpty(dst); @@ -272,22 +248,17 @@ public static void Scale(float a, float[] src, float[] dst, int count) Contracts.Assert(count <= src.Length); Contracts.Assert(count <= dst.Length); - Scale(a, new Span(src, 0, count), new Span(dst, 0, count)); - } - - private static void Scale(float a, Span src, Span dst) - { if (Avx.IsSupported) { - AvxIntrinsics.ScaleSrcU(a, src, dst); + AvxIntrinsics.ScaleSrcU(a, src, dst, count); } else if (Sse.IsSupported) { - SseIntrinsics.ScaleSrcU(a, src, dst); + SseIntrinsics.ScaleSrcU(a, src, dst, count); } else { - for (int i = 0; i < dst.Length; i++) + for (int i = 0; i < count; i++) { dst[i] = a * src[i]; } @@ -295,17 +266,10 @@ private static void Scale(float a, Span src, Span dst) } // dst[i] = a * (dst[i] + b) - public static void ScaleAdd(float a, float b, float[] dst, int count) + public static void ScaleAdd(float a, float b, Span dst) { Contracts.AssertNonEmpty(dst); - Contracts.Assert(count > 0); - Contracts.Assert(count <= dst.Length); - - ScaleAdd(a, b, new Span(dst, 0, count)); - } - private static void ScaleAdd(float a, float b, Span dst) - { if (Avx.IsSupported) { AvxIntrinsics.ScaleAddU(a, b, dst); @@ -323,7 +287,7 @@ private static void ScaleAdd(float a, float b, Span dst) } } - public static void AddScale(float a, float[] src, float[] dst, int count) + public static void AddScale(float a, ReadOnlySpan src, Span dst, int count) { Contracts.AssertNonEmpty(src); Contracts.AssertNonEmpty(dst); @@ -331,42 +295,24 @@ public static void AddScale(float a, float[] src, float[] dst, int count) Contracts.Assert(count <= src.Length); Contracts.Assert(count <= dst.Length); - AddScale(a, new Span(src, 0, count), new Span(dst, 0, count)); - } - - public static void AddScale(float a, float[] src, float[] dst, int dstOffset, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.AssertNonEmpty(dst); - Contracts.Assert(dstOffset >= 0); - Contracts.Assert(dstOffset < dst.Length); - Contracts.Assert(count > 0); - Contracts.Assert(count <= src.Length); - Contracts.Assert(count <= (dst.Length - dstOffset)); - - AddScale(a, new Span(src, 0, count), new Span(dst, dstOffset, count)); - } - - private static void AddScale(float a, Span src, Span dst) - { if (Avx.IsSupported) { - AvxIntrinsics.AddScaleU(a, src, dst); + AvxIntrinsics.AddScaleU(a, src, dst, count); } else if (Sse.IsSupported) { - SseIntrinsics.AddScaleU(a, src, dst); + SseIntrinsics.AddScaleU(a, src, dst, count); } else { - for (int i = 0; i < dst.Length; i++) + for (int i = 0; i < count; i++) { dst[i] += a * src[i]; } } } - public static void AddScale(float a, float[] src, int[] indices, float[] dst, int count) + public static void AddScale(float a, ReadOnlySpan src, ReadOnlySpan indices, Span dst, int count) { Contracts.AssertNonEmpty(src); Contracts.AssertNonEmpty(indices); @@ -376,38 +322,17 @@ public static void AddScale(float a, float[] src, int[] indices, float[] dst, in Contracts.Assert(count <= indices.Length); Contracts.Assert(count < dst.Length); - AddScale(a, new Span(src), new Span(indices, 0, count), new Span(dst)); - } - - public static void AddScale(float a, float[] src, int[] indices, float[] dst, int dstOffset, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.AssertNonEmpty(indices); - Contracts.AssertNonEmpty(dst); - Contracts.Assert(dstOffset >= 0); - Contracts.Assert(dstOffset < dst.Length); - Contracts.Assert(count > 0); - Contracts.Assert(count <= src.Length); - Contracts.Assert(count <= indices.Length); - Contracts.Assert(count < (dst.Length - dstOffset)); - - AddScale(a, new Span(src), new Span(indices, 0, count), - new Span(dst, dstOffset, dst.Length - dstOffset)); - } - - private static void AddScale(float a, Span src, Span indices, Span dst) - { if (Avx.IsSupported) { - AvxIntrinsics.AddScaleSU(a, src, indices, dst); + AvxIntrinsics.AddScaleSU(a, src, indices, dst, count); } else if (Sse.IsSupported) { - SseIntrinsics.AddScaleSU(a, src, indices, dst); + SseIntrinsics.AddScaleSU(a, src, indices, dst, count); } else { - for (int i = 0; i < indices.Length; i++) + for (int i = 0; i < count; i++) { int index = indices[i]; dst[index] += a * src[i]; @@ -415,7 +340,7 @@ private static void AddScale(float a, Span src, Span indices, Span src, ReadOnlySpan dst, Span res, int count) { Contracts.AssertNonEmpty(src); Contracts.AssertNonEmpty(dst); @@ -425,29 +350,24 @@ public static void AddScaleCopy(float a, float[] src, float[] dst, float[] res, Contracts.Assert(count <= dst.Length); Contracts.Assert(count <= res.Length); - AddScaleCopy(a, new Span(src, 0, count), new Span(dst, 0, count), new Span(res, 0, count)); - } - - private static void AddScaleCopy(float a, Span src, Span dst, Span res) - { if (Avx.IsSupported) { - AvxIntrinsics.AddScaleCopyU(a, src, dst, res); + AvxIntrinsics.AddScaleCopyU(a, src, dst, res, count); } else if (Sse.IsSupported) { - SseIntrinsics.AddScaleCopyU(a, src, dst, res); + SseIntrinsics.AddScaleCopyU(a, src, dst, res, count); } else { - for (int i = 0; i < res.Length; i++) + for (int i = 0; i < count; i++) { res[i] = a * src[i] + dst[i]; } } } - public static void Add(float[] src, float[] dst, int count) + public static void Add(ReadOnlySpan src, Span dst, int count) { Contracts.AssertNonEmpty(src); Contracts.AssertNonEmpty(dst); @@ -455,29 +375,24 @@ public static void Add(float[] src, float[] dst, int count) Contracts.Assert(count <= src.Length); Contracts.Assert(count <= dst.Length); - Add(new Span(src, 0, count), new Span(dst, 0, count)); - } - - private static void Add(Span src, Span dst) - { if (Avx.IsSupported) { - AvxIntrinsics.AddU(src, dst); + AvxIntrinsics.AddU(src, dst, count); } else if (Sse.IsSupported) { - SseIntrinsics.AddU(src, dst); + SseIntrinsics.AddU(src, dst, count); } else { - for (int i = 0; i < dst.Length; i++) + for (int i = 0; i < count; i++) { dst[i] += src[i]; } } } - public static void Add(float[] src, int[] indices, float[] dst, int count) + public static void Add(ReadOnlySpan src, ReadOnlySpan indices, Span dst, int count) { Contracts.AssertNonEmpty(src); Contracts.AssertNonEmpty(indices); @@ -487,38 +402,17 @@ public static void Add(float[] src, int[] indices, float[] dst, int count) Contracts.Assert(count <= indices.Length); Contracts.Assert(count < dst.Length); - Add(new Span(src), new Span(indices, 0, count), new Span(dst)); - } - - public static void Add(float[] src, int[] indices, float[] dst, int dstOffset, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.AssertNonEmpty(indices); - Contracts.AssertNonEmpty(dst); - Contracts.Assert(dstOffset >= 0); - Contracts.Assert(dstOffset < dst.Length); - Contracts.Assert(count > 0); - Contracts.Assert(count <= src.Length); - Contracts.Assert(count <= indices.Length); - Contracts.Assert(count <= (dst.Length - dstOffset)); - - Add(new Span(src), new Span(indices, 0, count), - new Span(dst, dstOffset, dst.Length - dstOffset)); - } - - private static void Add(Span src, Span indices, Span dst) - { if (Avx.IsSupported) { - AvxIntrinsics.AddSU(src, indices, dst); + AvxIntrinsics.AddSU(src, indices, dst, count); } else if (Sse.IsSupported) { - SseIntrinsics.AddSU(src, indices, dst); + SseIntrinsics.AddSU(src, indices, dst, count); } else { - for (int i = 0; i < indices.Length; i++) + for (int i = 0; i < count; i++) { int index = indices[i]; dst[index] += src[i]; @@ -526,7 +420,7 @@ private static void Add(Span src, Span indices, Span dst) } } - public static void MulElementWise(float[] src1, float[] src2, float[] dst, int count) + public static void MulElementWise(ReadOnlySpan src1, ReadOnlySpan src2, Span dst, int count) { Contracts.AssertNonEmpty(src1); Contracts.AssertNonEmpty(src2); @@ -534,51 +428,29 @@ public static void MulElementWise(float[] src1, float[] src2, float[] dst, int c Contracts.Assert(count > 0); Contracts.Assert(count <= src1.Length); Contracts.Assert(count <= src2.Length); + Contracts.Assert(count <= dst.Length); - MulElementWise(new Span(src1, 0, count), new Span(src2, 0, count), - new Span(dst, 0, count)); - } - - private static void MulElementWise(Span src1, Span src2, Span dst) - { if (Avx.IsSupported) { - AvxIntrinsics.MulElementWiseU(src1, src2, dst); + AvxIntrinsics.MulElementWiseU(src1, src2, dst, count); } else if (Sse.IsSupported) { - SseIntrinsics.MulElementWiseU(src1, src2, dst); + SseIntrinsics.MulElementWiseU(src1, src2, dst, count); } else { - for (int i = 0; i < dst.Length; i++) + for (int i = 0; i < count; i++) { dst[i] = src1[i] * src2[i]; } } } - public static float Sum(float[] src, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(count <= src.Length); - - return Sum(new Span(src, 0, count)); - } - - public static float Sum(float[] src, int offset, int count) + public static float Sum(ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(offset >= 0); - Contracts.Assert(offset <= (src.Length - count)); - - return Sum(new Span(src, offset, count)); - } - private static float Sum(Span src) - { if (Avx.IsSupported) { return AvxIntrinsics.SumU(src); @@ -598,27 +470,10 @@ private static float Sum(Span src) } } - public static float SumSq(float[] src, int count) + public static float SumSq(ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(count <= src.Length); - - return SumSq(new Span(src, 0, count)); - } - public static float SumSq(float[] src, int offset, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(offset >= 0); - Contracts.Assert(offset <= (src.Length - count)); - - return SumSq(new Span(src, offset, count)); - } - - private static float SumSq(Span src) - { if (Avx.IsSupported) { return AvxIntrinsics.SumSqU(src); @@ -638,18 +493,10 @@ private static float SumSq(Span src) } } - public static float SumSq(float mean, float[] src, int offset, int count) + public static float SumSq(float mean, ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(offset >= 0); - Contracts.Assert(offset <= (src.Length - count)); - - return SumSq(mean, new Span(src, offset, count)); - } - private static float SumSq(float mean, Span src) - { if (Avx.IsSupported) { return (mean == 0) ? AvxIntrinsics.SumSqU(src) : AvxIntrinsics.SumSqDiffU(mean, src); @@ -669,27 +516,10 @@ private static float SumSq(float mean, Span src) } } - public static float SumAbs(float[] src, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(count <= src.Length); - - return SumAbs(new Span(src, 0, count)); - } - - public static float SumAbs(float[] src, int offset, int count) + public static float SumAbs(ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(offset >= 0); - Contracts.Assert(offset <= (src.Length - count)); - - return SumAbs(new Span(src, offset, count)); - } - private static float SumAbs(Span src) - { if (Avx.IsSupported) { return AvxIntrinsics.SumAbsU(src); @@ -709,18 +539,10 @@ private static float SumAbs(Span src) } } - public static float SumAbs(float mean, float[] src, int offset, int count) + public static float SumAbs(float mean, ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(offset >= 0); - Contracts.Assert(offset <= (src.Length - count)); - return SumAbs(mean, new Span(src, offset, count)); - } - - private static float SumAbs(float mean, Span src) - { if (Avx.IsSupported) { return (mean == 0) ? AvxIntrinsics.SumAbsU(src) : AvxIntrinsics.SumAbsDiffU(mean, src); @@ -740,27 +562,10 @@ private static float SumAbs(float mean, Span src) } } - public static float MaxAbs(float[] src, int count) + public static float MaxAbs(ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(count <= src.Length); - - return MaxAbs(new Span(src, 0, count)); - } - - public static float MaxAbs(float[] src, int offset, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(offset >= 0); - Contracts.Assert(offset <= (src.Length - count)); - - return MaxAbs(new Span(src, offset, count)); - } - private static float MaxAbs(Span src) - { if (Avx.IsSupported) { return AvxIntrinsics.MaxAbsU(src); @@ -784,17 +589,10 @@ private static float MaxAbs(Span src) } } - public static float MaxAbsDiff(float mean, float[] src, int count) + public static float MaxAbsDiff(float mean, ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(count > 0); - Contracts.Assert(count <= src.Length); - return MaxAbsDiff(mean, new Span(src, 0, count)); - } - - private static float MaxAbsDiff(float mean, Span src) - { if (Avx.IsSupported) { return AvxIntrinsics.MaxAbsDiffU(mean, src); @@ -818,7 +616,7 @@ private static float MaxAbsDiff(float mean, Span src) } } - public static float DotProductDense(float[] a, float[] b, int count) + public static float DotProductDense(ReadOnlySpan a, ReadOnlySpan b, int count) { Contracts.AssertNonEmpty(a); Contracts.AssertNonEmpty(b); @@ -826,35 +624,18 @@ public static float DotProductDense(float[] a, float[] b, int count) Contracts.Assert(a.Length >= count); Contracts.Assert(b.Length >= count); - return DotProductDense(new Span(a, 0, count), new Span(b, 0, count)); - } - - public static float DotProductDense(float[] a, int offset, float[] b, int count) - { - Contracts.AssertNonEmpty(a); - Contracts.AssertNonEmpty(b); - Contracts.Assert(count > 0); - Contracts.Assert(count <= b.Length); - Contracts.Assert(offset >= 0); - Contracts.Assert(offset <= (a.Length - count)); - - return DotProductDense(new Span(a, offset, count), new Span(b, 0, count)); - } - - private static float DotProductDense(Span a, Span b) - { if (Avx.IsSupported) { - return AvxIntrinsics.DotU(a, b); + return AvxIntrinsics.DotU(a, b, count); } else if (Sse.IsSupported) { - return SseIntrinsics.DotU(a, b); + return SseIntrinsics.DotU(a, b, count); } else { float result = 0; - for (int i = 0; i < b.Length; i++) + for (int i = 0; i < count; i++) { result += a[i] * b[i]; } @@ -862,7 +643,7 @@ private static float DotProductDense(Span a, Span b) } } - public static float DotProductSparse(float[] a, float[] b, int[] indices, int count) + public static float DotProductSparse(ReadOnlySpan a, ReadOnlySpan b, ReadOnlySpan indices, int count) { Contracts.AssertNonEmpty(a); Contracts.AssertNonEmpty(b); @@ -872,40 +653,18 @@ public static float DotProductSparse(float[] a, float[] b, int[] indices, int co Contracts.Assert(count <= b.Length); Contracts.Assert(count <= indices.Length); - return DotProductSparse(new Span(a), new Span(b), - new Span(indices, 0, count)); - } - - public static float DotProductSparse(float[] a, int offset, float[] b, int[] indices, int count) - { - Contracts.AssertNonEmpty(a); - Contracts.AssertNonEmpty(b); - Contracts.AssertNonEmpty(indices); - Contracts.Assert(count > 0); - Contracts.Assert(count < (a.Length - offset)); - Contracts.Assert(count <= b.Length); - Contracts.Assert(count <= indices.Length); - Contracts.Assert(offset >= 0); - Contracts.Assert(offset < a.Length); - - return DotProductSparse(new Span(a, offset, a.Length - offset), - new Span(b), new Span(indices, 0, count)); - } - - private static float DotProductSparse(Span a, Span b, Span indices) - { if (Avx.IsSupported) { - return AvxIntrinsics.DotSU(a, b, indices); + return AvxIntrinsics.DotSU(a, b, indices, count); } else if (Sse.IsSupported) { - return SseIntrinsics.DotSU(a, b, indices); + return SseIntrinsics.DotSU(a, b, indices, count); } else { float result = 0; - for (int i = 0; i < indices.Length; i++) + for (int i = 0; i < count; i++) { int index = indices[i]; result += a[index] * b[i]; @@ -914,7 +673,7 @@ private static float DotProductSparse(Span a, Span b, Span in } } - public static float L2DistSquared(float[] a, float[] b, int count) + public static float L2DistSquared(ReadOnlySpan a, ReadOnlySpan b, int count) { Contracts.AssertNonEmpty(a); Contracts.AssertNonEmpty(b); @@ -922,23 +681,18 @@ public static float L2DistSquared(float[] a, float[] b, int count) Contracts.Assert(count <= a.Length); Contracts.Assert(count <= b.Length); - return L2DistSquared(new Span(a, 0, count), new Span(b, 0, count)); - } - - private static float L2DistSquared(Span a, Span b) - { if (Avx.IsSupported) { - return AvxIntrinsics.Dist2(a, b); + return AvxIntrinsics.Dist2(a, b, count); } else if (Sse.IsSupported) { - return SseIntrinsics.Dist2(a, b); + return SseIntrinsics.Dist2(a, b, count); } else { float norm = 0; - for (int i = 0; i < b.Length; i++) + for (int i = 0; i < count; i++) { float distance = a[i] - b[i]; norm += distance * distance; @@ -1012,32 +766,27 @@ private static unsafe void ZeroMatrixItemsCore(AlignedArray dst, int c, int ccol } } - public static void SdcaL1UpdateDense(float primalUpdate, int length, float[] src, float threshold, float[] v, float[] w) + public static void SdcaL1UpdateDense(float primalUpdate, int count, ReadOnlySpan src, float threshold, Span v, Span w) { Contracts.AssertNonEmpty(src); Contracts.AssertNonEmpty(v); Contracts.AssertNonEmpty(w); - Contracts.Assert(length > 0); - Contracts.Assert(length <= src.Length); - Contracts.Assert(length <= v.Length); - Contracts.Assert(length <= w.Length); - - SdcaL1UpdateDense(primalUpdate, new Span(src, 0, length), threshold, new Span(v, 0, length), new Span(w, 0, length)); - } + Contracts.Assert(count > 0); + Contracts.Assert(count <= src.Length); + Contracts.Assert(count <= v.Length); + Contracts.Assert(count <= w.Length); - private static void SdcaL1UpdateDense(float primalUpdate, Span src, float threshold, Span v, Span w) - { if (Avx.IsSupported) { - AvxIntrinsics.SdcaL1UpdateU(primalUpdate, src, threshold, v, w); + AvxIntrinsics.SdcaL1UpdateU(primalUpdate, count, src, threshold, v, w); } else if (Sse.IsSupported) { - SseIntrinsics.SdcaL1UpdateU(primalUpdate, src, threshold, v, w); + SseIntrinsics.SdcaL1UpdateU(primalUpdate, count, src, threshold, v, w); } else { - for (int i = 0; i < src.Length; i++) + for (int i = 0; i < count; i++) { v[i] += src[i] * primalUpdate; float value = v[i]; @@ -1046,8 +795,7 @@ private static void SdcaL1UpdateDense(float primalUpdate, Span src, float } } - // REVIEW NEEDED: The second argument "length" is unused even in the existing code. - public static void SdcaL1UpdateSparse(float primalUpdate, int length, float[] src, int[] indices, int count, float threshold, float[] v, float[] w) + public static void SdcaL1UpdateSparse(float primalUpdate, int count, ReadOnlySpan src, ReadOnlySpan indices, float threshold, Span v, Span w) { Contracts.AssertNonEmpty(src); Contracts.AssertNonEmpty(indices); @@ -1056,26 +804,20 @@ public static void SdcaL1UpdateSparse(float primalUpdate, int length, float[] sr Contracts.Assert(count > 0); Contracts.Assert(count <= src.Length); Contracts.Assert(count <= indices.Length); - Contracts.Assert(count < length); - Contracts.Assert(length <= v.Length); - Contracts.Assert(length <= w.Length); + Contracts.Assert(count <= v.Length); + Contracts.Assert(count <= w.Length); - SdcaL1UpdateSparse(primalUpdate, new Span(src, 0, count), new Span(indices, 0, count), threshold, new Span(v), new Span(w)); - } - - private static void SdcaL1UpdateSparse(float primalUpdate, Span src, Span indices, float threshold, Span v, Span w) - { if (Avx.IsSupported) { - AvxIntrinsics.SdcaL1UpdateSU(primalUpdate, src, indices, threshold, v, w); + AvxIntrinsics.SdcaL1UpdateSU(primalUpdate, count, src, indices, threshold, v, w); } else if (Sse.IsSupported) { - SseIntrinsics.SdcaL1UpdateSU(primalUpdate, src, indices, threshold, v, w); + SseIntrinsics.SdcaL1UpdateSU(primalUpdate, count, src, indices, threshold, v, w); } else { - for (int i = 0; i < indices.Length; i++) + for (int i = 0; i < count; i++) { int index = indices[i]; v[index] += src[i] * primalUpdate; diff --git a/src/Microsoft.ML.CpuMath/CpuMathUtils.netstandard.cs b/src/Microsoft.ML.CpuMath/CpuMathUtils.netstandard.cs index b35f171388..927bf32673 100644 --- a/src/Microsoft.ML.CpuMath/CpuMathUtils.netstandard.cs +++ b/src/Microsoft.ML.CpuMath/CpuMathUtils.netstandard.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Runtime.CompilerServices; namespace Microsoft.ML.Runtime.Internal.CpuMath @@ -20,72 +21,52 @@ public static int GetVectorAlignment() public static void MatTimesSrc(bool tran, bool add, AlignedArray mat, int[] rgposSrc, AlignedArray srcValues, int posMin, int iposMin, int iposLim, AlignedArray dst, int crun) => SseUtils.MatTimesSrc(tran, add, mat, rgposSrc, srcValues, posMin, iposMin, iposLim, dst, crun); - public static void Add(float a, float[] dst, int count) => SseUtils.Add(a, dst, count); + public static void Add(float a, Span dst) => SseUtils.Add(a, dst); - public static void Scale(float a, float[] dst, int count) => SseUtils.Scale(a, dst, count); + public static void Scale(float a, Span dst) => SseUtils.Scale(a, dst); - public static void Scale(float a, float[] dst, int offset, int count) => SseUtils.Scale(a, dst, offset, count); + public static void Scale(float a, ReadOnlySpan src, Span dst, int count) => SseUtils.Scale(a, src, dst, count); - public static void Scale(float a, float[] src, float[] dst, int count) => SseUtils.Scale(a, src, dst, count); + public static void ScaleAdd(float a, float b, Span dst) => SseUtils.ScaleAdd(a, b, dst); - public static void ScaleAdd(float a, float b, float[] dst, int count) => SseUtils.ScaleAdd(a, b, dst, count); + public static void AddScale(float a, ReadOnlySpan src, Span dst, int count) => SseUtils.AddScale(a, src, dst, count); - public static void AddScale(float a, float[] src, float[] dst, int count) => SseUtils.AddScale(a, src, dst, count); + public static void AddScale(float a, ReadOnlySpan src, ReadOnlySpan indices, Span dst, int count) => SseUtils.AddScale(a, src, indices, dst, count); - public static void AddScale(float a, float[] src, float[] dst, int dstOffset, int count) => SseUtils.AddScale(a, src, dst, dstOffset, count); + public static void AddScaleCopy(float a, ReadOnlySpan src, ReadOnlySpan dst, Span res, int count) => SseUtils.AddScaleCopy(a, src, dst, res, count); - public static void AddScale(float a, float[] src, int[] indices, float[] dst, int count) => SseUtils.AddScale(a, src, indices, dst, count); + public static void Add(ReadOnlySpan src, Span dst, int count) => SseUtils.Add(src, dst, count); - public static void AddScale(float a, float[] src, int[] indices, float[] dst, int dstOffset, int count) => SseUtils.AddScale(a, src, indices, dst, dstOffset, count); + public static void Add(ReadOnlySpan src, ReadOnlySpan indices, Span dst, int count) => SseUtils.Add(src, indices, dst, count); - public static void AddScaleCopy(float a, float[] src, float[] dst, float[] res, int count) => SseUtils.AddScaleCopy(a, src, dst, res, count); + public static void MulElementWise(ReadOnlySpan src1, ReadOnlySpan src2, Span dst, int count) => SseUtils.MulElementWise(src1, src2, dst, count); - public static void Add(float[] src, float[] dst, int count) => SseUtils.Add(src, dst, count); + public static float Sum(ReadOnlySpan src) => SseUtils.Sum(src); - public static void Add(float[] src, int[] indices, float[] dst, int count) => SseUtils.Add(src, indices, dst, count); + public static float SumSq(ReadOnlySpan src) => SseUtils.SumSq(src); - public static void Add(float[] src, int[] indices, float[] dst, int dstOffset, int count) => SseUtils.Add(src, indices, dst, dstOffset, count); + public static float SumSq(float mean, ReadOnlySpan src) => SseUtils.SumSq(mean, src); - public static void MulElementWise(float[] src1, float[] src2, float[] dst, int count) => SseUtils.MulElementWise(src1, src2, dst, count); + public static float SumAbs(ReadOnlySpan src) => SseUtils.SumAbs(src); - public static float Sum(float[] src, int count) => SseUtils.Sum(src, count); + public static float SumAbs(float mean, ReadOnlySpan src) => SseUtils.SumAbs(mean, src); - public static float Sum(float[] src, int offset, int count) => SseUtils.Sum(src, offset, count); + public static float MaxAbs(ReadOnlySpan src) => SseUtils.MaxAbs(src); - public static float SumSq(float[] src, int count) => SseUtils.SumSq(src, count); + public static float MaxAbsDiff(float mean, ReadOnlySpan src) => SseUtils.MaxAbsDiff(mean, src); - public static float SumSq(float[] src, int offset, int count) => SseUtils.SumSq(src, offset, count); + public static float DotProductDense(ReadOnlySpan a, ReadOnlySpan b, int count) => SseUtils.DotProductDense(a, b, count); - public static float SumSq(float mean, float[] src, int offset, int count) => SseUtils.SumSq(mean, src, offset, count); + public static float DotProductSparse(ReadOnlySpan a, ReadOnlySpan b, ReadOnlySpan indices, int count) => SseUtils.DotProductSparse(a, b, indices, count); - public static float SumAbs(float[] src, int count) => SseUtils.SumAbs(src, count); - - public static float SumAbs(float[] src, int offset, int count) => SseUtils.SumAbs(src, offset, count); - - public static float SumAbs(float mean, float[] src, int offset, int count) => SseUtils.SumAbs(mean, src, offset, count); - - public static float MaxAbs(float[] src, int count) => SseUtils.MaxAbs(src, count); - - public static float MaxAbs(float[] src, int offset, int count) => SseUtils.MaxAbs(src, offset, count); - - public static float MaxAbsDiff(float mean, float[] src, int count) => SseUtils.MaxAbsDiff(mean, src, count); - - public static float DotProductDense(float[] a, float[] b, int count) => SseUtils.DotProductDense(a, b, count); - - public static float DotProductDense(float[] a, int offset, float[] b, int count) => SseUtils.DotProductDense(a, offset, b, count); - - public static float DotProductSparse(float[] a, float[] b, int[] indices, int count) => SseUtils.DotProductSparse(a, b, indices, count); - - public static float DotProductSparse(float[] a, int offset, float[] b, int[] indices, int count) => SseUtils.DotProductSparse(a, offset, b, indices, count); - - public static float L2DistSquared(float[] a, float[] b, int count) => SseUtils.L2DistSquared(a, b, count); + public static float L2DistSquared(ReadOnlySpan a, ReadOnlySpan b, int count) => SseUtils.L2DistSquared(a, b, count); public static void ZeroMatrixItems(AlignedArray dst, int ccol, int cfltRow, int[] indices) => SseUtils.ZeroMatrixItems(dst, ccol, cfltRow, indices); - public static void SdcaL1UpdateDense(float primalUpdate, int length, float[] src, float threshold, float[] v, float[] w) - => SseUtils.SdcaL1UpdateDense(primalUpdate, length, src, threshold, v, w); + public static void SdcaL1UpdateDense(float primalUpdate, int count, ReadOnlySpan src, float threshold, Span v, Span w) + => SseUtils.SdcaL1UpdateDense(primalUpdate, count, src, threshold, v, w); - public static void SdcaL1UpdateSparse(float primalUpdate, int length, float[] src, int[] indices, int count, float threshold, float[] v, float[] w) - => SseUtils.SdcaL1UpdateSparse(primalUpdate, length, src, indices, count, threshold, v, w); + public static void SdcaL1UpdateSparse(float primalUpdate, int count, ReadOnlySpan src, ReadOnlySpan indices, float threshold, Span v, Span w) + => SseUtils.SdcaL1UpdateSparse(primalUpdate, count, src, indices, threshold, v, w); } } diff --git a/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj b/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj index c55f5a4f1d..9fe8615a8c 100644 --- a/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj +++ b/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj @@ -28,6 +28,7 @@ + \ No newline at end of file diff --git a/src/Microsoft.ML.CpuMath/Sse.cs b/src/Microsoft.ML.CpuMath/Sse.cs index d541c02533..7bca076b14 100644 --- a/src/Microsoft.ML.CpuMath/Sse.cs +++ b/src/Microsoft.ML.CpuMath/Sse.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; + namespace Microsoft.ML.Runtime.Internal.CpuMath { /// @@ -586,16 +588,14 @@ public static void AddXYTran(AlignedArray x, int[] rgposY, AlignedArray valuesY, } // dst += a - public static void Add(float a, float[] dst, int count) + public static void Add(float a, Span dst) { Contracts.AssertNonEmpty(dst); - Contracts.Assert(0 < count); - Contracts.Assert(0 < count && count <= dst.Length); unsafe { - fixed (float* pdst = &dst[0]) - Thunk.AddScalarU(a, pdst, count); + fixed (float* pdst = dst) + Thunk.AddScalarU(a, pdst, dst.Length); } } @@ -610,15 +610,14 @@ public static void Scale(float a, AlignedArray dst) } } - public static void Scale(float a, float[] dst, int count) + public static void Scale(float a, Span dst) { Contracts.AssertNonEmpty(dst); - Contracts.Assert(0 < count && count <= dst.Length); unsafe { - fixed (float* pd = &dst[0]) - Thunk.Scale(a, pd, count); + fixed (float* pd = dst) + Thunk.Scale(a, pd, dst.Length); } } @@ -636,7 +635,7 @@ public static void Scale(float a, float[] dst, int offset, int count) } // dst = a * src - public static void Scale(float a, float[] src, float[] dst, int count) + public static void Scale(float a, ReadOnlySpan src, Span dst, int count) { Contracts.AssertNonEmpty(src); Contracts.Assert(0 < count && count <= src.Length); @@ -645,8 +644,8 @@ public static void Scale(float a, float[] src, float[] dst, int count) unsafe { - fixed (float* psrc = &src[0]) - fixed (float* pdst = &dst[0]) + fixed (float* psrc = src) + fixed (float* pdst = dst) { Thunk.ScaleSrcU(a, psrc, pdst, count); } @@ -654,16 +653,14 @@ public static void Scale(float a, float[] src, float[] dst, int count) } // dst[i] = a * (dst[i] + b) - public static void ScaleAdd(float a, float b, float[] dst, int count) + public static void ScaleAdd(float a, float b, Span dst) { Contracts.AssertNonEmpty(dst); - Contracts.Assert(0 < count); - Contracts.Assert(0 < count && count <= dst.Length); unsafe { - fixed (float* pdst = &dst[0]) - Thunk.ScaleAddU(a, b, pdst, count); + fixed (float* pdst = dst) + Thunk.ScaleAddU(a, b, pdst, dst.Length); } } @@ -759,7 +756,7 @@ public static void AddScale(float a, AlignedArray src, AlignedArray dst, float m } } - public static void AddScale(float a, float[] src, float[] dst, int count) + public static void AddScale(float a, ReadOnlySpan src, Span dst, int count) { Contracts.AssertNonEmpty(src); Contracts.Assert(0 < count && count <= src.Length); @@ -768,29 +765,13 @@ public static void AddScale(float a, float[] src, float[] dst, int count) unsafe { - fixed (float* psrc = &src[0]) - fixed (float* pdst = &dst[0]) + fixed (float* psrc = src) + fixed (float* pdst = dst) Thunk.AddScaleU(a, psrc, pdst, count); } } - public static void AddScale(float a, float[] src, float[] dst, int dstOffset, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(count <= src.Length); - Contracts.AssertNonEmpty(dst); - Contracts.Assert(0 <= dstOffset && dstOffset < dst.Length); - Contracts.Assert(0 < count && count <= dst.Length - dstOffset); - - unsafe - { - fixed (float* psrc = &src[0]) - fixed (float* pdst = &dst[dstOffset]) - Thunk.AddScaleU(a, psrc, pdst, count); - } - } - - public static void AddScale(float a, float[] src, int[] indices, float[] dst, int count) + public static void AddScale(float a, ReadOnlySpan src, ReadOnlySpan indices, Span dst, int count) { Contracts.AssertNonEmpty(src); Contracts.Assert(0 < count && count <= src.Length); @@ -801,14 +782,14 @@ public static void AddScale(float a, float[] src, int[] indices, float[] dst, in unsafe { - fixed (float* psrc = &src[0]) - fixed (int* pi = &indices[0]) - fixed (float* pdst = &dst[0]) + fixed (float* psrc = src) + fixed (int* pi = indices) + fixed (float* pdst = dst) Thunk.AddScaleSU(a, psrc, pi, pdst, count); } } - public static void AddScaleCopy(float a, float[] src, float[] dst, float[] res, int count) + public static void AddScaleCopy(float a, ReadOnlySpan src, ReadOnlySpan dst, Span res, int count) { Contracts.AssertNonEmpty(dst); Contracts.Assert(0 < count && count <= dst.Length); @@ -819,33 +800,13 @@ public static void AddScaleCopy(float a, float[] src, float[] dst, float[] res, unsafe { - fixed (float* pdst = &dst[0]) - fixed (float* psrc = &src[0]) - fixed (float* pres = &res[0]) + fixed (float* pdst = dst) + fixed (float* psrc = src) + fixed (float* pres = res) Thunk.AddScaleCopyU(a, psrc, pdst, pres, count); } } - public static void AddScale(float a, float[] src, int[] indices, float[] dst, - int dstOffset, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count && count <= src.Length); - Contracts.AssertNonEmpty(indices); - Contracts.Assert(count <= indices.Length); - Contracts.AssertNonEmpty(dst); - Contracts.Assert(0 <= dstOffset && dstOffset < dst.Length); - Contracts.Assert(count < dst.Length - dstOffset); - - unsafe - { - fixed (float* psrc = &src[0]) - fixed (int* pi = &indices[0]) - fixed (float* pdst = &dst[dstOffset]) - Thunk.AddScaleSU(a, psrc, pi, pdst, count); - } - } - public static void AddScale(AlignedArray src, AlignedArray dst, AlignedArray accGrads, AlignedArray accUpdates, float decay, float cond) { @@ -881,7 +842,7 @@ public static void Add(AlignedArray src, AlignedArray dst) } } - public static void Add(float[] src, float[] dst, int count) + public static void Add(ReadOnlySpan src, Span dst, int count) { Contracts.AssertNonEmpty(src); Contracts.Assert(0 < count && count <= src.Length); @@ -890,13 +851,13 @@ public static void Add(float[] src, float[] dst, int count) unsafe { - fixed (float* ps = &src[0]) - fixed (float* pd = &dst[0]) + fixed (float* ps = src) + fixed (float* pd = dst) Thunk.AddU(ps, pd, count); } } - public static void Add(float[] src, int[] indices, float[] dst, int count) + public static void Add(ReadOnlySpan src, ReadOnlySpan indices, Span dst, int count) { Contracts.AssertNonEmpty(src); Contracts.Assert(0 < count && count <= src.Length); @@ -907,33 +868,14 @@ public static void Add(float[] src, int[] indices, float[] dst, int count) unsafe { - fixed (float* ps = &src[0]) - fixed (int* pi = &indices[0]) - fixed (float* pd = &dst[0]) - Thunk.AddSU(ps, pi, pd, count); - } - } - - public static void Add(float[] src, int[] indices, float[] dst, int dstOffset, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count && count <= src.Length); - Contracts.AssertNonEmpty(indices); - Contracts.Assert(count <= indices.Length); - Contracts.AssertNonEmpty(dst); - Contracts.Assert(0 <= dstOffset && dstOffset < dst.Length); - Contracts.Assert(count <= dst.Length - dstOffset); - - unsafe - { - fixed (float* ps = &src[0]) - fixed (int* pi = &indices[0]) - fixed (float* pd = &dst[dstOffset]) + fixed (float* ps = src) + fixed (int* pi = indices) + fixed (float* pd = dst) Thunk.AddSU(ps, pi, pd, count); } } - public static void MulElementWise(float[] src1, float[] src2, float[] dst, int count) + public static void MulElementWise(ReadOnlySpan src1, ReadOnlySpan src2, Span dst, int count) { Contracts.AssertNonEmpty(src1); Contracts.Assert(0 < count && count <= src1.Length); @@ -942,9 +884,9 @@ public static void MulElementWise(float[] src1, float[] src2, float[] dst, int c Contracts.AssertNonEmpty(dst); unsafe { - fixed (float* ps1 = &src1[0]) - fixed (float* ps2 = &src2[0]) - fixed (float* pd = &dst[0]) + fixed (float* ps1 = src1) + fixed (float* ps2 = src2) + fixed (float* pd = dst) Thunk.MulElementWiseU(ps1, ps2, pd, count); } } @@ -979,145 +921,84 @@ public static float Sum(AlignedArray src) } } - public static float Sum(float[] src, int count) + public static float Sum(ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count && count <= src.Length); unsafe { - fixed (float* psrc = &src[0]) - return Thunk.SumU(psrc, count); + fixed (float* psrc = src) + return Thunk.SumU(psrc, src.Length); } } - public static float Sum(float[] src, int offset, int count) + public static float SumSq(ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count); - Contracts.Assert(0 <= offset && offset <= src.Length - count); unsafe { - fixed (float* psrc = &src[offset]) - return Thunk.SumU(psrc, count); + fixed (float* psrc = src) + return Thunk.SumSqU(psrc, src.Length); } } - public static float SumSq(float[] src, int count) + public static float SumSq(float mean, ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count && count <= src.Length); unsafe { - fixed (float* psrc = &src[0]) - return Thunk.SumSqU(psrc, count); + fixed (float* psrc = src) + return (mean == 0 ? Thunk.SumSqU(psrc, src.Length) : Thunk.SumSqDiffU(mean, psrc, src.Length)); } } - public static float SumSq(float[] src, int offset, int count) + public static float SumAbs(ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count); - Contracts.Assert(0 <= offset && offset <= src.Length - count); unsafe { - fixed (float* psrc = &src[offset]) - return Thunk.SumSqU(psrc, count); + fixed (float* psrc = src) + return Thunk.SumAbsU(psrc, src.Length); } } - public static float SumSq(float mean, float[] src, int offset, int count) + public static float SumAbs(float mean, ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count); - Contracts.Assert(0 <= offset && offset <= src.Length - count); unsafe { - fixed (float* psrc = &src[offset]) - return (mean == 0 ? Thunk.SumSqU(psrc, count) : Thunk.SumSqDiffU(mean, psrc, count)); + fixed (float* psrc = src) + return (mean == 0 ? Thunk.SumAbsU(psrc, src.Length) : Thunk.SumAbsDiffU(mean, psrc, src.Length)); } } - public static float SumAbs(float[] src, int count) + public static float MaxAbs(ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count && count <= src.Length); unsafe { - fixed (float* psrc = &src[0]) - return Thunk.SumAbsU(psrc, count); - } - } - - public static float SumAbs(float[] src, int offset, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count); - Contracts.Assert(0 <= offset && offset <= src.Length - count); - - unsafe - { - fixed (float* psrc = &src[offset]) - return Thunk.SumAbsU(psrc, count); - } - } - - public static float SumAbs(float mean, float[] src, int offset, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count); - Contracts.Assert(0 <= offset && offset <= src.Length - count); - - unsafe - { - fixed (float* psrc = &src[offset]) - return (mean == 0 ? Thunk.SumAbsU(psrc, count) : Thunk.SumAbsDiffU(mean, psrc, count)); - } - } - - public static float MaxAbs(float[] src, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count && count <= src.Length); - - unsafe - { - fixed (float* psrc = &src[0]) + fixed (float* psrc = src) return Thunk.MaxAbsU(psrc, src.Length); } } - public static float MaxAbsDiff(float mean, float[] src, int count) - { - Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count && count <= src.Length); - - unsafe - { - fixed (float* psrc = &src[0]) - return Thunk.MaxAbsDiffU(mean, psrc, count); - } - } - - public static float MaxAbs(float[] src, int offset, int count) + public static float MaxAbsDiff(float mean, ReadOnlySpan src) { Contracts.AssertNonEmpty(src); - Contracts.Assert(0 < count); - Contracts.Assert(0 <= offset && offset <= src.Length - count); unsafe { - fixed (float* psrc = &src[offset]) - return Thunk.MaxAbsU(psrc, count); + fixed (float* psrc = src) + return Thunk.MaxAbsDiffU(mean, psrc, src.Length); } } - public static float DotProductDense(float[] a, float[] b, int count) + public static float DotProductDense(ReadOnlySpan a, ReadOnlySpan b, int count) { Contracts.AssertNonEmpty(a); Contracts.AssertNonEmpty(b); @@ -1127,29 +1008,13 @@ public static float DotProductDense(float[] a, float[] b, int count) unsafe { - fixed (float* pa = &a[0]) - fixed (float* pb = &b[0]) + fixed (float* pa = a) + fixed (float* pb = b) return Thunk.DotU(pa, pb, count); } } - public static float DotProductDense(float[] a, int offset, float[] b, int count) - { - Contracts.AssertNonEmpty(a); - Contracts.Assert(0 < count); - Contracts.Assert(0 <= offset && offset <= a.Length - count); - Contracts.AssertNonEmpty(b); - Contracts.Assert(b.Length >= count); - - unsafe - { - fixed (float* pa = &a[offset]) - fixed (float* pb = &b[0]) - return Thunk.DotU(pa, pb, count); - } - } - - public static float DotProductSparse(float[] a, float[] b, int[] indices, int count) + public static float DotProductSparse(ReadOnlySpan a, ReadOnlySpan b, ReadOnlySpan indices, int count) { Contracts.AssertNonEmpty(a); Contracts.AssertNonEmpty(b); @@ -1160,33 +1025,14 @@ public static float DotProductSparse(float[] a, float[] b, int[] indices, int co unsafe { - fixed (float* pa = &a[0]) - fixed (float* pb = &b[0]) - fixed (int* pi = &indices[0]) - return Thunk.DotSU(pa, pb, pi, count); - } - } - - public static float DotProductSparse(float[] a, int offset, float[] b, int[] indices, int count) - { - Contracts.AssertNonEmpty(a); - Contracts.Assert(0 < count); - Contracts.Assert(0 <= offset && offset < a.Length); - Contracts.Assert(a.Length - offset > count); - Contracts.AssertNonEmpty(b); - Contracts.Assert(count <= b.Length); - Contracts.Assert(count <= indices.Length); - - unsafe - { - fixed (float* pa = &a[offset]) - fixed (float* pb = &b[0]) - fixed (int* pi = &indices[0]) + fixed (float* pa = a) + fixed (float* pb = b) + fixed (int* pi = indices) return Thunk.DotSU(pa, pb, pi, count); } } - public static float L2DistSquared(float[] a, float[] b, int count) + public static float L2DistSquared(ReadOnlySpan a, ReadOnlySpan b, int count) { Contracts.AssertNonEmpty(a); Contracts.AssertNonEmpty(b); @@ -1195,8 +1041,8 @@ public static float L2DistSquared(float[] a, float[] b, int count) unsafe { - fixed (float* pa = &a[0]) - fixed (float* pb = &b[0]) + fixed (float* pa = a) + fixed (float* pb = b) return Thunk.Dist2(pa, pb, count); } } @@ -1474,44 +1320,43 @@ public static void ZeroMatrixItems(AlignedArray dst, int ccol, int cfltRow, int[ } } - public static void SdcaL1UpdateDense(float primalUpdate, int length, float[] src, float threshold, float[] v, float[] w) + public static void SdcaL1UpdateDense(float primalUpdate, int count, ReadOnlySpan src, float threshold, Span v, Span w) { Contracts.AssertNonEmpty(src); - Contracts.Assert(length <= src.Length); + Contracts.Assert(count <= src.Length); Contracts.AssertNonEmpty(v); - Contracts.Assert(length <= v.Length); + Contracts.Assert(count <= v.Length); Contracts.AssertNonEmpty(w); - Contracts.Assert(length <= w.Length); - Contracts.Assert(length > 0); + Contracts.Assert(count <= w.Length); + Contracts.Assert(count > 0); unsafe { - fixed (float* psrc = &src[0]) - fixed (float* pd1 = &v[0]) - fixed (float* pd2 = &w[0]) - Thunk.SdcaL1UpdateU(primalUpdate, psrc, threshold, pd1, pd2, length); + fixed (float* psrc = src) + fixed (float* pd1 = v) + fixed (float* pd2 = w) + Thunk.SdcaL1UpdateU(primalUpdate, psrc, threshold, pd1, pd2, count); } } - public static void SdcaL1UpdateSparse(float primalUpdate, int length, float[] src, int[] indices, int count, float threshold, float[] v, float[] w) + public static void SdcaL1UpdateSparse(float primalUpdate, int count, ReadOnlySpan src, ReadOnlySpan indices, float threshold, Span v, Span w) { Contracts.AssertNonEmpty(src); Contracts.Assert(count <= src.Length); Contracts.AssertNonEmpty(indices); Contracts.Assert(count <= indices.Length); - Contracts.AssertNonEmpty(w); - Contracts.Assert(length <= w.Length); Contracts.AssertNonEmpty(v); - Contracts.Assert(length <= v.Length); - Contracts.Assert(0 < count); - Contracts.Assert(count < length); + Contracts.Assert(count <= v.Length); + Contracts.AssertNonEmpty(w); + Contracts.Assert(count <= w.Length); + Contracts.Assert(count > 0); unsafe { - fixed (float* psrc = &src[0]) - fixed (int* pi = &indices[0]) - fixed (float* pd1 = &v[0]) - fixed (float* pd2 = &w[0]) + fixed (float* psrc = src) + fixed (int* pi = indices) + fixed (float* pd1 = v) + fixed (float* pd2 = w) Thunk.SdcaL1UpdateSU(primalUpdate, psrc, pi, threshold, pd1, pd2, count); } } diff --git a/src/Microsoft.ML.CpuMath/SseIntrinsics.cs b/src/Microsoft.ML.CpuMath/SseIntrinsics.cs index ede8a7da97..71b7afcd8f 100644 --- a/src/Microsoft.ML.CpuMath/SseIntrinsics.cs +++ b/src/Microsoft.ML.CpuMath/SseIntrinsics.cs @@ -526,7 +526,7 @@ public static unsafe void Scale(float scale, Span dst) for (float* pEnd = pDstCurrent + (length - remainder); pDstCurrent < pEnd; pDstCurrent += 4) { - // If we aren't using the VEX-encoding, the JIT will only fold away aligned loads + // If we aren't using the VEX-encoding, the JIT will only fold away aligned loads // (due to semantics of the legacy encoding). // We don't need an assert, since the instruction will throw for unaligned inputs. Vector128 temp = Sse.LoadAlignedVector128(pDstCurrent); @@ -566,12 +566,12 @@ public static unsafe void Scale(float scale, Span dst) } } - public static unsafe void ScaleSrcU(float scale, Span src, Span dst) + public static unsafe void ScaleSrcU(float scale, ReadOnlySpan src, Span dst, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) { - float* pDstEnd = pdst + dst.Length; + float* pDstEnd = pdst + count; float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -632,14 +632,14 @@ public static unsafe void ScaleAddU(float a, float b, Span dst) } } - public static unsafe void AddScaleU(float scale, Span src, Span dst) + public static unsafe void AddScaleU(float scale, ReadOnlySpan src, Span dst, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; - float* pEnd = pdst + dst.Length; + float* pEnd = pdst + count; Vector128 scaleVector = Sse.SetAllVector128(scale); @@ -671,13 +671,13 @@ public static unsafe void AddScaleU(float scale, Span src, Span ds } } - public static unsafe void AddScaleCopyU(float scale, Span src, Span dst, Span result) + public static unsafe void AddScaleCopyU(float scale, ReadOnlySpan src, ReadOnlySpan dst, Span result, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) fixed (float* pres = result) { - float* pResEnd = pres + result.Length; + float* pResEnd = pres + count; float* pSrcCurrent = psrc; float* pDstCurrent = pdst; float* pResCurrent = pres; @@ -712,7 +712,7 @@ public static unsafe void AddScaleCopyU(float scale, Span src, Span src, Span idx, Span dst) + public static unsafe void AddScaleSU(float scale, ReadOnlySpan src, ReadOnlySpan idx, Span dst, int count) { fixed (float* psrc = src) fixed (int* pidx = idx) @@ -721,7 +721,7 @@ public static unsafe void AddScaleSU(float scale, Span src, Span idx float* pSrcCurrent = psrc; int* pIdxCurrent = pidx; float* pDstCurrent = pdst; - int* pEnd = pidx + idx.Length; + int* pEnd = pidx + count; Vector128 scaleVector = Sse.SetAllVector128(scale); @@ -748,14 +748,14 @@ public static unsafe void AddScaleSU(float scale, Span src, Span idx } } - public static unsafe void AddU(Span src, Span dst) + public static unsafe void AddU(ReadOnlySpan src, Span dst, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; - float* pEnd = psrc + src.Length; + float* pEnd = psrc + count; while (pSrcCurrent + 4 <= pEnd) { @@ -783,7 +783,7 @@ public static unsafe void AddU(Span src, Span dst) } } - public static unsafe void AddSU(Span src, Span idx, Span dst) + public static unsafe void AddSU(ReadOnlySpan src, ReadOnlySpan idx, Span dst, int count) { fixed (float* psrc = src) fixed (int* pidx = idx) @@ -792,7 +792,7 @@ public static unsafe void AddSU(Span src, Span idx, Span dst) float* pSrcCurrent = psrc; int* pIdxCurrent = pidx; float* pDstCurrent = pdst; - int* pEnd = pidx + idx.Length; + int* pEnd = pidx + count; while (pIdxCurrent + 4 <= pEnd) { @@ -816,7 +816,7 @@ public static unsafe void AddSU(Span src, Span idx, Span dst) } } - public static unsafe void MulElementWiseU(Span src1, Span src2, Span dst) + public static unsafe void MulElementWiseU(ReadOnlySpan src1, ReadOnlySpan src2, Span dst, int count) { fixed (float* psrc1 = &src1[0]) fixed (float* psrc2 = &src2[0]) @@ -825,7 +825,7 @@ public static unsafe void MulElementWiseU(Span src1, Span src2, Sp float* pSrc1Current = psrc1; float* pSrc2Current = psrc2; float* pDstCurrent = pdst; - float* pEnd = pdst + dst.Length; + float* pEnd = pdst + count; while (pDstCurrent + 4 <= pEnd) { @@ -853,7 +853,7 @@ public static unsafe void MulElementWiseU(Span src1, Span src2, Sp } } - public static unsafe float SumU(Span src) + public static unsafe float SumU(ReadOnlySpan src) { fixed (float* psrc = src) { @@ -880,7 +880,7 @@ public static unsafe float SumU(Span src) } } - public static unsafe float SumSqU(Span src) + public static unsafe float SumSqU(ReadOnlySpan src) { fixed (float* psrc = src) { @@ -911,7 +911,7 @@ public static unsafe float SumSqU(Span src) } } - public static unsafe float SumSqDiffU(float mean, Span src) + public static unsafe float SumSqDiffU(float mean, ReadOnlySpan src) { fixed (float* psrc = src) { @@ -945,7 +945,7 @@ public static unsafe float SumSqDiffU(float mean, Span src) } } - public static unsafe float SumAbsU(Span src) + public static unsafe float SumAbsU(ReadOnlySpan src) { fixed (float* psrc = src) { @@ -976,7 +976,7 @@ public static unsafe float SumAbsU(Span src) } } - public static unsafe float SumAbsDiffU(float mean, Span src) + public static unsafe float SumAbsDiffU(float mean, ReadOnlySpan src) { fixed (float* psrc = src) { @@ -1010,7 +1010,7 @@ public static unsafe float SumAbsDiffU(float mean, Span src) } } - public static unsafe float MaxAbsU(Span src) + public static unsafe float MaxAbsU(ReadOnlySpan src) { fixed (float* psrc = src) { @@ -1041,7 +1041,7 @@ public static unsafe float MaxAbsU(Span src) } } - public static unsafe float MaxAbsDiffU(float mean, Span src) + public static unsafe float MaxAbsDiffU(float mean, ReadOnlySpan src) { fixed (float* psrc = src) { @@ -1075,14 +1075,14 @@ public static unsafe float MaxAbsDiffU(float mean, Span src) } } - public static unsafe float DotU(Span src, Span dst) + public static unsafe float DotU(ReadOnlySpan src, ReadOnlySpan dst, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; - float* pSrcEnd = psrc + src.Length; + float* pSrcEnd = psrc + count; Vector128 result = Sse.SetZeroVector128(); @@ -1114,7 +1114,7 @@ public static unsafe float DotU(Span src, Span dst) } } - public static unsafe float DotSU(Span src, Span dst, Span idx) + public static unsafe float DotSU(ReadOnlySpan src, ReadOnlySpan dst, ReadOnlySpan idx, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) @@ -1123,7 +1123,7 @@ public static unsafe float DotSU(Span src, Span dst, Span idx float* pSrcCurrent = psrc; float* pDstCurrent = pdst; int* pIdxCurrent = pidx; - int* pIdxEnd = pidx + idx.Length; + int* pIdxEnd = pidx + count; Vector128 result = Sse.SetZeroVector128(); @@ -1155,14 +1155,14 @@ public static unsafe float DotSU(Span src, Span dst, Span idx } } - public static unsafe float Dist2(Span src, Span dst) + public static unsafe float Dist2(ReadOnlySpan src, ReadOnlySpan dst, int count) { fixed (float* psrc = src) fixed (float* pdst = dst) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; - float* pSrcEnd = psrc + src.Length; + float* pSrcEnd = psrc + count; Vector128 sqDistanceVector = Sse.SetZeroVector128(); @@ -1193,13 +1193,13 @@ public static unsafe float Dist2(Span src, Span dst) } } - public static unsafe void SdcaL1UpdateU(float primalUpdate, Span src, float threshold, Span v, Span w) + public static unsafe void SdcaL1UpdateU(float primalUpdate, int count, ReadOnlySpan src, float threshold, Span v, Span w) { fixed (float* psrc = src) fixed (float* pdst1 = v) fixed (float* pdst2 = w) { - float* pSrcEnd = psrc + src.Length; + float* pSrcEnd = psrc + count; float* pSrcCurrent = psrc; float* pDst1Current = pdst1; float* pDst2Current = pdst2; @@ -1238,14 +1238,14 @@ public static unsafe void SdcaL1UpdateU(float primalUpdate, Span src, flo } } - public static unsafe void SdcaL1UpdateSU(float primalUpdate, Span src, Span indices, float threshold, Span v, Span w) + public static unsafe void SdcaL1UpdateSU(float primalUpdate, int count, ReadOnlySpan src, ReadOnlySpan indices, float threshold, Span v, Span w) { fixed (float* psrc = src) fixed (int* pidx = indices) fixed (float* pdst1 = v) fixed (float* pdst2 = w) { - int* pIdxEnd = pidx + indices.Length; + int* pIdxEnd = pidx + count; float* pSrcCurrent = psrc; int* pIdxCurrent = pidx; diff --git a/src/Microsoft.ML.Data/Depricated/Vector/VBufferMathUtils.cs b/src/Microsoft.ML.Data/Depricated/Vector/VBufferMathUtils.cs index c8a7d3d241..b8dba514df 100644 --- a/src/Microsoft.ML.Data/Depricated/Vector/VBufferMathUtils.cs +++ b/src/Microsoft.ML.Data/Depricated/Vector/VBufferMathUtils.cs @@ -22,7 +22,7 @@ public static Float NormSquared(in VBuffer a) { if (a.Count == 0) return 0; - return CpuMathUtils.SumSq(a.Values, 0, a.Count); + return CpuMathUtils.SumSq(a.Values.AsSpan(0, a.Count)); } /// @@ -30,7 +30,7 @@ public static Float NormSquared(in VBuffer a) /// public static Float NormSquared(Float[] a, int offset, int count) { - return CpuMathUtils.SumSq(a, offset, count); + return CpuMathUtils.SumSq(a.AsSpan(offset, count)); } /// @@ -50,7 +50,7 @@ public static Float L1Norm(ref VBuffer a) { if (a.Count == 0) return 0; - return CpuMathUtils.SumAbs(a.Values, 0, a.Count); + return CpuMathUtils.SumAbs(a.Values.AsSpan(0, a.Count)); } /// @@ -61,7 +61,7 @@ public static Float MaxNorm(ref VBuffer a) { if (a.Count == 0) return 0; - return CpuMathUtils.MaxAbs(a.Values, 0, a.Count); + return CpuMathUtils.MaxAbs(a.Values.AsSpan(0, a.Count)); } /// @@ -71,7 +71,7 @@ public static Float Sum(ref VBuffer a) { if (a.Count == 0) return 0; - return CpuMathUtils.Sum(a.Values, 0, a.Count); + return CpuMathUtils.Sum(a.Values.AsSpan(0, a.Count)); } /// @@ -84,7 +84,7 @@ public static void ScaleBy(ref VBuffer dst, Float c) if (c == 1 || dst.Count == 0) return; if (c != 0) - CpuMathUtils.Scale(c, dst.Values, dst.Count); + CpuMathUtils.Scale(c, dst.Values.AsSpan(0, dst.Count)); else // Maintain density of dst. Array.Clear(dst.Values, 0, dst.Count); // REVIEW: Any benefit in sparsifying? @@ -239,9 +239,9 @@ public static void AddMultWithOffset(ref VBuffer src, Float c, ref VBuffe { // This is by far the most common case. if (src.IsDense) - CpuMathUtils.AddScale(c, src.Values, dst.Values, offset, src.Count); + CpuMathUtils.AddScale(c, src.Values, dst.Values.AsSpan(offset), src.Count); else - CpuMathUtils.AddScale(c, src.Values, src.Indices, dst.Values, offset, src.Count); + CpuMathUtils.AddScale(c, src.Values, src.Indices, dst.Values.AsSpan(offset), src.Count); return; } // REVIEW: Perhaps implementing an ApplyInto with an offset would be more diff --git a/src/Microsoft.ML.Data/Depricated/Vector/VectorUtils.cs b/src/Microsoft.ML.Data/Depricated/Vector/VectorUtils.cs index 5b2df5b486..54eada4623 100644 --- a/src/Microsoft.ML.Data/Depricated/Vector/VectorUtils.cs +++ b/src/Microsoft.ML.Data/Depricated/Vector/VectorUtils.cs @@ -228,10 +228,10 @@ private static Float L2DistSquaredHalfSparse(Float[] valuesA, int lengthA, Float Contracts.Assert(0 <= countB && countB <= Utils.Size(indicesB)); Contracts.Assert(countB <= Utils.Size(valuesB)); - var normA = CpuMathUtils.SumSq(valuesA, 0, lengthA); + var normA = CpuMathUtils.SumSq(valuesA.AsSpan(0, lengthA)); if (countB == 0) return normA; - var normB = CpuMathUtils.SumSq(valuesB, 0, countB); + var normB = CpuMathUtils.SumSq(valuesB.AsSpan(0, countB)); var dotP = CpuMathUtils.DotProductSparse(valuesA, valuesB, indicesB, countB); var res = normA + normB - 2 * dotP; return res < 0 ? 0 : res; @@ -267,8 +267,8 @@ public static Float DotProductWithOffset(ref VBuffer a, int offset, ref V if (a.IsDense) { if (b.IsDense) - return CpuMathUtils.DotProductDense(a.Values, offset, b.Values, b.Length); - return CpuMathUtils.DotProductSparse(a.Values, offset, b.Values, b.Indices, b.Count); + return CpuMathUtils.DotProductDense(a.Values.AsSpan(offset), b.Values, b.Length); + return CpuMathUtils.DotProductSparse(a.Values.AsSpan(offset), b.Values, b.Indices, b.Count); } else { @@ -314,8 +314,8 @@ public static Float DotProductWithOffset(Float[] a, int offset, ref VBuffer public static Float Norm(Float[] a) { - return MathUtils.Sqrt(CpuMathUtils.SumSq(a, a.Length)); + return MathUtils.Sqrt(CpuMathUtils.SumSq(a)); } /// @@ -520,7 +520,7 @@ public static Float Sum(Float[] a) { if (a == null || a.Length == 0) return 0; - return CpuMathUtils.Sum(a, a.Length); + return CpuMathUtils.Sum(a); } /// @@ -534,7 +534,7 @@ public static void ScaleBy(Float[] dst, Float c) return; if (c != 0) - CpuMathUtils.Scale(c, dst, dst.Length); + CpuMathUtils.Scale(c, dst); else Array.Clear(dst, 0, dst.Length); } diff --git a/src/Microsoft.ML.StandardLearners/Standard/LinearClassificationTrainer.cs b/src/Microsoft.ML.StandardLearners/Standard/LinearClassificationTrainer.cs index ab4f5826a1..9158f31974 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/LinearClassificationTrainer.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/LinearClassificationTrainer.cs @@ -803,9 +803,9 @@ protected virtual void TrainWithoutLock(IProgressChannelProvider progress, Float } if (features.IsDense) - CpuMathUtils.SdcaL1UpdateDense(primalUpdate, features.Length, features.Values, l1Threshold, l1IntermediateWeights[0].Values, weights[0].Values); + CpuMathUtils.SdcaL1UpdateDense(primalUpdate, features.Count, features.Values, l1Threshold, l1IntermediateWeights[0].Values, weights[0].Values); else if (features.Count > 0) - CpuMathUtils.SdcaL1UpdateSparse(primalUpdate, features.Length, features.Values, features.Indices, features.Count, l1Threshold, l1IntermediateWeights[0].Values, weights[0].Values); + CpuMathUtils.SdcaL1UpdateSparse(primalUpdate, features.Count, features.Values, features.Indices, l1Threshold, l1IntermediateWeights[0].Values, weights[0].Values); } break; diff --git a/src/Microsoft.ML.StandardLearners/Standard/SdcaMultiClass.cs b/src/Microsoft.ML.StandardLearners/Standard/SdcaMultiClass.cs index 4b8b0aa6bf..e7dea180e6 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/SdcaMultiClass.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/SdcaMultiClass.cs @@ -210,9 +210,9 @@ protected override void TrainWithoutLock(IProgressChannelProvider progress, Floa } if (features.IsDense) - CpuMathUtils.SdcaL1UpdateDense(-primalUpdate, features.Length, features.Values, l1Threshold, l1IntermediateWeights[iClass].Values, weights[iClass].Values); + CpuMathUtils.SdcaL1UpdateDense(-primalUpdate, features.Count, features.Values, l1Threshold, l1IntermediateWeights[iClass].Values, weights[iClass].Values); else if (features.Count > 0) - CpuMathUtils.SdcaL1UpdateSparse(-primalUpdate, features.Length, features.Values, features.Indices, features.Count, l1Threshold, l1IntermediateWeights[iClass].Values, weights[iClass].Values); + CpuMathUtils.SdcaL1UpdateSparse(-primalUpdate, features.Count, features.Values, features.Indices, l1Threshold, l1IntermediateWeights[iClass].Values, weights[iClass].Values); } break; @@ -237,9 +237,9 @@ protected override void TrainWithoutLock(IProgressChannelProvider progress, Floa : 0; if (features.IsDense) - CpuMathUtils.SdcaL1UpdateDense(labelPrimalUpdate, features.Length, features.Values, l1Threshold, l1IntermediateWeights[label].Values, weights[label].Values); + CpuMathUtils.SdcaL1UpdateDense(labelPrimalUpdate, features.Count, features.Values, l1Threshold, l1IntermediateWeights[label].Values, weights[label].Values); else if (features.Count > 0) - CpuMathUtils.SdcaL1UpdateSparse(labelPrimalUpdate, features.Length, features.Values, features.Indices, features.Count, l1Threshold, l1IntermediateWeights[label].Values, weights[label].Values); + CpuMathUtils.SdcaL1UpdateSparse(labelPrimalUpdate, features.Count, features.Values, features.Indices, l1Threshold, l1IntermediateWeights[label].Values, weights[label].Values); } rowCount++; diff --git a/src/Microsoft.ML.Transforms/GcnTransform.cs b/src/Microsoft.ML.Transforms/GcnTransform.cs index 4a3324f7ce..0f42621d72 100644 --- a/src/Microsoft.ML.Transforms/GcnTransform.cs +++ b/src/Microsoft.ML.Transforms/GcnTransform.cs @@ -575,9 +575,9 @@ private static void FillValues(IExceptionContext ectx, ref VBuffer src, r src.CopyToDense(ref dst); if (normScale != 1) - CpuMathUtils.ScaleAdd(normScale, -offset, dst.Values, length); + CpuMathUtils.ScaleAdd(normScale, -offset, dst.Values.AsSpan(0, length)); else - CpuMathUtils.Add(-offset, dst.Values, length); + CpuMathUtils.Add(-offset, dst.Values.AsSpan(0, length)); } /// @@ -591,7 +591,7 @@ private static Float StdDev(Float[] values, int count, int length) if (count == 0) return 0; // We need a mean to compute variance. - Float tmpMean = CpuMathUtils.Sum(values, 0, count) / length; + Float tmpMean = CpuMathUtils.Sum(values.AsSpan(0, count)) / length; Float sumSq = 0; if (count != length && tmpMean != 0) { @@ -599,7 +599,7 @@ private static Float StdDev(Float[] values, int count, int length) Float meanSq = tmpMean * tmpMean; sumSq = (length - count) * meanSq; } - sumSq += CpuMathUtils.SumSq(tmpMean, values, 0, count); + sumSq += CpuMathUtils.SumSq(tmpMean, values.AsSpan(0, count)); return MathUtils.Sqrt(sumSq / length); } @@ -619,7 +619,7 @@ private static Float StdDev(Float[] values, int count, int length, Float mean) Float meanSq = mean * mean; sumSq = (length - count) * meanSq; } - sumSq += CpuMathUtils.SumSq(mean, values, 0, count); + sumSq += CpuMathUtils.SumSq(mean, values.AsSpan(0, count)); return MathUtils.Sqrt(sumSq / length); } @@ -631,7 +631,7 @@ private static Float L2Norm(Float[] values, int count, Float mean = 0) { if (count == 0) return 0; - return MathUtils.Sqrt(CpuMathUtils.SumSq(mean, values, 0, count)); + return MathUtils.Sqrt(CpuMathUtils.SumSq(mean, values.AsSpan(0, count))); } /// @@ -642,7 +642,7 @@ private static Float L1Norm(Float[] values, int count, Float mean = 0) { if (count == 0) return 0; - return CpuMathUtils.SumAbs(mean, values, 0, count); + return CpuMathUtils.SumAbs(mean, values.AsSpan(0, count)); } /// @@ -653,14 +653,14 @@ private static Float LInfNorm(Float[] values, int count, Float mean = 0) { if (count == 0) return 0; - return CpuMathUtils.MaxAbsDiff(mean, values, count); + return CpuMathUtils.MaxAbsDiff(mean, values.AsSpan(0, count)); } private static Float Mean(Float[] src, int count, int length) { if (length == 0 || count == 0) return 0; - return CpuMathUtils.Sum(src, 0, count) / length; + return CpuMathUtils.Sum(src.AsSpan(0, count)) / length; } } diff --git a/src/Microsoft.ML.Transforms/WhiteningTransform.cs b/src/Microsoft.ML.Transforms/WhiteningTransform.cs index 14a47559f1..d5a5ca1455 100644 --- a/src/Microsoft.ML.Transforms/WhiteningTransform.cs +++ b/src/Microsoft.ML.Transforms/WhiteningTransform.cs @@ -582,7 +582,7 @@ private static void FillValues(Float[] model, ref VBuffer src, ref VBuffe private static Float DotProduct(Float[] a, int aOffset, Float[] b, int[] indices, int count) { Contracts.Assert(count <= indices.Length); - return CpuMathUtils.DotProductSparse(a, aOffset, b, indices, count); + return CpuMathUtils.DotProductSparse(a.AsSpan(aOffset), b, indices, count); } diff --git a/test/Microsoft.ML.Benchmarks.Tests/BenchmarksTest.cs b/test/Microsoft.ML.Benchmarks.Tests/BenchmarksTest.cs index d4e8499df3..79bbd601da 100644 --- a/test/Microsoft.ML.Benchmarks.Tests/BenchmarksTest.cs +++ b/test/Microsoft.ML.Benchmarks.Tests/BenchmarksTest.cs @@ -23,7 +23,7 @@ public class TestConfig : RecommendedConfig public class BenchmarkTouchingNativeDependency { [Benchmark] - public float Simple() => CpuMathUtils.Sum(Enumerable.Range(0, 1024).Select(Convert.ToSingle).ToArray(), 1024); + public float Simple() => CpuMathUtils.Sum(Enumerable.Range(0, 1024).Select(Convert.ToSingle).ToArray()); } public class BenchmarksTest diff --git a/test/Microsoft.ML.CpuMath.PerformanceTests/AvxPerformanceTests.cs b/test/Microsoft.ML.CpuMath.PerformanceTests/AvxPerformanceTests.cs index 5930090bc5..b9deabd455 100644 --- a/test/Microsoft.ML.CpuMath.PerformanceTests/AvxPerformanceTests.cs +++ b/test/Microsoft.ML.CpuMath.PerformanceTests/AvxPerformanceTests.cs @@ -21,7 +21,7 @@ public void Scale() [Benchmark] public void ScaleSrcU() - => AvxIntrinsics.ScaleSrcU(DefaultScale, new Span(src, 0, Length), new Span(dst, 0, Length)); + => AvxIntrinsics.ScaleSrcU(DefaultScale, src, dst, Length); [Benchmark] public void ScaleAddU() @@ -29,28 +29,27 @@ public void ScaleAddU() [Benchmark] public void AddScaleU() - => AvxIntrinsics.AddScaleU(DefaultScale, new Span(src, 0, Length), new Span(dst, 0, Length)); + => AvxIntrinsics.AddScaleU(DefaultScale, src, dst, Length); [Benchmark] public void AddScaleSU() - => AvxIntrinsics.AddScaleSU(DefaultScale, new Span(src), new Span(idx, 0, IndexLength), new Span(dst)); + => AvxIntrinsics.AddScaleSU(DefaultScale, src, idx, dst, IndexLength); [Benchmark] public void AddScaleCopyU() - => AvxIntrinsics.AddScaleCopyU(DefaultScale, new Span(src, 0, Length), new Span(dst, 0, Length), new Span(result, 0, Length)); + => AvxIntrinsics.AddScaleCopyU(DefaultScale, src, dst, result, Length); [Benchmark] public void AddU() - => AvxIntrinsics.AddU(new Span(src, 0, Length), new Span(dst, 0, Length)); + => AvxIntrinsics.AddU(src, dst, Length); [Benchmark] public void AddSU() - => AvxIntrinsics.AddSU(new Span(src), new Span(idx, 0, IndexLength), new Span(dst)); + => AvxIntrinsics.AddSU(src, idx, dst, IndexLength); [Benchmark] public void MulElementWiseU() - => AvxIntrinsics.MulElementWiseU(new Span(src1, 0, Length), new Span(src2, 0, Length), - new Span(dst, 0, Length)); + => AvxIntrinsics.MulElementWiseU(src1, src2, dst, Length); [Benchmark] public float SumU() @@ -82,22 +81,22 @@ public float MaxAbsDiffU() [Benchmark] public float DotU() - => AvxIntrinsics.DotU(new Span(src, 0, Length), new Span(dst, 0, Length)); + => AvxIntrinsics.DotU(src, dst, Length); [Benchmark] public float DotSU() - => AvxIntrinsics.DotSU(new Span(src), new Span(dst), new Span(idx, 0, IndexLength)); + => AvxIntrinsics.DotSU(src, dst, idx, IndexLength); [Benchmark] public float Dist2() - => AvxIntrinsics.Dist2(new Span(src, 0, Length), new Span(dst, 0, Length)); + => AvxIntrinsics.Dist2(src, dst, Length); [Benchmark] public void SdcaL1UpdateU() - => AvxIntrinsics.SdcaL1UpdateU(DefaultScale, new Span(src, 0, Length), DefaultScale, new Span(dst, 0, Length), new Span(result, 0, Length)); + => AvxIntrinsics.SdcaL1UpdateU(DefaultScale, Length, src, DefaultScale, dst, result); [Benchmark] public void SdcaL1UpdateSU() - => AvxIntrinsics.SdcaL1UpdateSU(DefaultScale, new Span(src, 0, IndexLength), new Span(idx, 0, IndexLength), DefaultScale, new Span(dst), new Span(result)); + => AvxIntrinsics.SdcaL1UpdateSU(DefaultScale, IndexLength, src, idx, DefaultScale, dst, result); } } diff --git a/test/Microsoft.ML.CpuMath.PerformanceTests/SsePerformanceTests.cs b/test/Microsoft.ML.CpuMath.PerformanceTests/SsePerformanceTests.cs index 923d7c539f..c10ad936c2 100644 --- a/test/Microsoft.ML.CpuMath.PerformanceTests/SsePerformanceTests.cs +++ b/test/Microsoft.ML.CpuMath.PerformanceTests/SsePerformanceTests.cs @@ -21,7 +21,7 @@ public void Scale() [Benchmark] public void ScaleSrcU() - => SseIntrinsics.ScaleSrcU(DefaultScale, new Span(src, 0, Length), new Span(dst, 0, Length)); + => SseIntrinsics.ScaleSrcU(DefaultScale, src, dst, Length); [Benchmark] public void ScaleAddU() @@ -29,28 +29,27 @@ public void ScaleAddU() [Benchmark] public void AddScaleU() - => SseIntrinsics.AddScaleU(DefaultScale, new Span(src, 0, Length), new Span(dst, 0, Length)); + => SseIntrinsics.AddScaleU(DefaultScale, src, dst, Length); [Benchmark] public void AddScaleSU() - => SseIntrinsics.AddScaleSU(DefaultScale, new Span(src), new Span(idx, 0, IndexLength), new Span(dst)); + => SseIntrinsics.AddScaleSU(DefaultScale, src, idx, dst, IndexLength); [Benchmark] public void AddScaleCopyU() - => SseIntrinsics.AddScaleCopyU(DefaultScale, new Span(src, 0, Length), new Span(dst, 0, Length), new Span(result, 0, Length)); + => SseIntrinsics.AddScaleCopyU(DefaultScale, src, dst, result, Length); [Benchmark] public void AddU() - => SseIntrinsics.AddU(new Span(src, 0, Length), new Span(dst, 0, Length)); + => SseIntrinsics.AddU(src, dst, Length); [Benchmark] public void AddSU() - => SseIntrinsics.AddSU(new Span(src), new Span(idx, 0, IndexLength), new Span(dst)); + => SseIntrinsics.AddSU(src, idx, dst, IndexLength); [Benchmark] public void MulElementWiseU() - => SseIntrinsics.MulElementWiseU(new Span(src1, 0, Length), new Span(src2, 0, Length), - new Span(dst, 0, Length)); + => SseIntrinsics.MulElementWiseU(src1, src2, dst, Length); [Benchmark] public float SumU() @@ -82,22 +81,22 @@ public float MaxAbsDiffU() [Benchmark] public float DotU() - => SseIntrinsics.DotU(new Span(src, 0, Length), new Span(dst, 0, Length)); + => SseIntrinsics.DotU(src, dst, Length); [Benchmark] public float DotSU() - => SseIntrinsics.DotSU(new Span(src), new Span(dst), new Span(idx, 0, IndexLength)); + => SseIntrinsics.DotSU(src, dst, idx, IndexLength); [Benchmark] public float Dist2() - => SseIntrinsics.Dist2(new Span(src, 0, Length), new Span(dst, 0, Length)); + => SseIntrinsics.Dist2(src, dst, Length); [Benchmark] public void SdcaL1UpdateU() - => SseIntrinsics.SdcaL1UpdateU(DefaultScale, new Span(src, 0, Length), DefaultScale, new Span(dst, 0, Length), new Span(result, 0, Length)); + => SseIntrinsics.SdcaL1UpdateU(DefaultScale, Length, src, DefaultScale, dst, result); [Benchmark] public void SdcaL1UpdateSU() - => SseIntrinsics.SdcaL1UpdateSU(DefaultScale, new Span(src, 0, IndexLength), new Span(idx, 0, IndexLength), DefaultScale, new Span(dst), new Span(result)); + => SseIntrinsics.SdcaL1UpdateSU(DefaultScale, IndexLength, src, idx, DefaultScale, dst, result); } } diff --git a/test/Microsoft.ML.CpuMath.UnitTests.netcoreapp/UnitTests.cs b/test/Microsoft.ML.CpuMath.UnitTests.netcoreapp/UnitTests.cs index 6c0f1cbaf0..7c92f747e2 100644 --- a/test/Microsoft.ML.CpuMath.UnitTests.netcoreapp/UnitTests.cs +++ b/test/Microsoft.ML.CpuMath.UnitTests.netcoreapp/UnitTests.cs @@ -225,7 +225,7 @@ public void AddScalarUTest(int test) expected[i] += DefaultScale; } - CpuMathUtils.Add(DefaultScale, dst, dst.Length); + CpuMathUtils.Add(DefaultScale, dst); var actual = dst; Assert.Equal(expected, actual, _comparer); } @@ -243,7 +243,7 @@ public void ScaleTest(int test) expected[i] *= DefaultScale; } - CpuMathUtils.Scale(DefaultScale, dst, dst.Length); + CpuMathUtils.Scale(DefaultScale, dst); var actual = dst; Assert.Equal(expected, actual, _comparer); } @@ -280,7 +280,7 @@ public void ScaleAddUTest(int test) expected[i] = DefaultScale * (dst[i] + DefaultScale); } - CpuMathUtils.ScaleAdd(DefaultScale, DefaultScale, dst, dst.Length); + CpuMathUtils.ScaleAdd(DefaultScale, DefaultScale, dst); var actual = dst; Assert.Equal(expected, actual, _comparer); } @@ -432,7 +432,7 @@ public void MulElementWiseUTest(int test) public void SumUTest(int test, float expected) { float[] src = (float[])_testArrays[test].Clone(); - var actual = CpuMathUtils.Sum(src, src.Length); + var actual = CpuMathUtils.Sum(src); Assert.Equal(expected, actual, 2); } @@ -442,7 +442,7 @@ public void SumUTest(int test, float expected) public void SumSqUTest(int test, float expected) { float[] src = (float[])_testArrays[test].Clone(); - var actual = CpuMathUtils.SumSq(src, src.Length); + var actual = CpuMathUtils.SumSq(src); Assert.Equal(expected, actual, 2); } @@ -452,7 +452,7 @@ public void SumSqUTest(int test, float expected) public void SumSqDiffUTest(int test, float expected) { float[] src = (float[])_testArrays[test].Clone(); - var actual = CpuMathUtils.SumSq(DefaultScale, src, 0, src.Length); + var actual = CpuMathUtils.SumSq(DefaultScale, src); Assert.Equal(expected, actual, 2); } @@ -462,7 +462,7 @@ public void SumSqDiffUTest(int test, float expected) public void SumAbsUTest(int test, float expected) { float[] src = (float[])_testArrays[test].Clone(); - var actual = CpuMathUtils.SumAbs(src, src.Length); + var actual = CpuMathUtils.SumAbs(src); Assert.Equal(expected, actual, 2); } @@ -472,7 +472,7 @@ public void SumAbsUTest(int test, float expected) public void SumAbsDiffUTest(int test, float expected) { float[] src = (float[])_testArrays[test].Clone(); - var actual = CpuMathUtils.SumAbs(DefaultScale, src, 0, src.Length); + var actual = CpuMathUtils.SumAbs(DefaultScale, src); Assert.Equal(expected, actual, 2); } @@ -482,7 +482,7 @@ public void SumAbsDiffUTest(int test, float expected) public void MaxAbsUTest(int test, float expected) { float[] src = (float[])_testArrays[test].Clone(); - var actual = CpuMathUtils.MaxAbs(src, src.Length); + var actual = CpuMathUtils.MaxAbs(src); Assert.Equal(expected, actual, 2); } @@ -492,7 +492,7 @@ public void MaxAbsUTest(int test, float expected) public void MaxAbsDiffUTest(int test, float expected) { float[] src = (float[])_testArrays[test].Clone(); - var actual = CpuMathUtils.MaxAbsDiff(DefaultScale, src, src.Length); + var actual = CpuMathUtils.MaxAbsDiff(DefaultScale, src); Assert.Equal(expected, actual, 2); } @@ -617,7 +617,7 @@ public void SdcaL1UpdateSUTest(int test) expected[index] = Math.Abs(value) > DefaultScale ? (value > 0 ? value - DefaultScale : value + DefaultScale) : 0; } - CpuMathUtils.SdcaL1UpdateSparse(DefaultScale, src.Length, src, idx, idx.Length, DefaultScale, v, w); + CpuMathUtils.SdcaL1UpdateSparse(DefaultScale, idx.Length, src, idx, DefaultScale, v, w); var actual = w; Assert.Equal(expected, actual, _comparer); } From ec4c943cedf3ab535d69bac83062255c542827da Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 12 Oct 2018 15:55:09 -0500 Subject: [PATCH 2/3] Use MemoryMarshal.GetReference to avoid perf hit when pinning Span. --- src/Microsoft.ML.CpuMath/AvxIntrinsics.cs | 85 ++++++++++++----------- src/Microsoft.ML.CpuMath/Sse.cs | 85 ++++++++++++----------- src/Microsoft.ML.CpuMath/SseIntrinsics.cs | 85 ++++++++++++----------- 3 files changed, 129 insertions(+), 126 deletions(-) diff --git a/src/Microsoft.ML.CpuMath/AvxIntrinsics.cs b/src/Microsoft.ML.CpuMath/AvxIntrinsics.cs index 2947c4a961..415f1656c4 100644 --- a/src/Microsoft.ML.CpuMath/AvxIntrinsics.cs +++ b/src/Microsoft.ML.CpuMath/AvxIntrinsics.cs @@ -11,6 +11,7 @@ using System; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; using nuint = System.UInt64; @@ -448,7 +449,7 @@ public static unsafe void MatMulTranPX(bool add, AlignedArray mat, int[] rgposSr // dst[i] += scale public static unsafe void AddScalarU(float scalar, Span dst) { - fixed (float* pdst = dst) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pDstEnd = pdst + dst.Length; float* pDstCurrent = pdst; @@ -490,7 +491,7 @@ public static unsafe void Scale(float scale, Span dst) { fixed (uint* pLeadingAlignmentMask = &LeadingAlignmentMask[0]) fixed (uint* pTrailingAlignmentMask = &TrailingAlignmentMask[0]) - fixed (float* pd = dst) + fixed (float* pd = &MemoryMarshal.GetReference(dst)) { float* pDstCurrent = pd; int length = dst.Length; @@ -608,8 +609,8 @@ public static unsafe void Scale(float scale, Span dst) public static unsafe void ScaleSrcU(float scale, ReadOnlySpan src, Span dst, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pDstEnd = pdst + count; float* pSrcCurrent = psrc; @@ -654,7 +655,7 @@ public static unsafe void ScaleSrcU(float scale, ReadOnlySpan src, Span dst) { - fixed (float* pdst = dst) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pDstEnd = pdst + dst.Length; float* pDstCurrent = pdst; @@ -699,8 +700,8 @@ public static unsafe void ScaleAddU(float a, float b, Span dst) public static unsafe void AddScaleU(float scale, ReadOnlySpan src, Span dst, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -753,9 +754,9 @@ public static unsafe void AddScaleU(float scale, ReadOnlySpan src, Span src, ReadOnlySpan dst, Span result, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) - fixed (float* pres = result) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) + fixed (float* pres = &MemoryMarshal.GetReference(result)) { float* pResEnd = pres + count; float* pSrcCurrent = psrc; @@ -809,9 +810,9 @@ public static unsafe void AddScaleCopyU(float scale, ReadOnlySpan src, Re public static unsafe void AddScaleSU(float scale, ReadOnlySpan src, ReadOnlySpan idx, Span dst, int count) { - fixed (float* psrc = src) - fixed (int* pidx = idx) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (int* pidx = &MemoryMarshal.GetReference(idx)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; int* pIdxCurrent = pidx; @@ -860,8 +861,8 @@ public static unsafe void AddScaleSU(float scale, ReadOnlySpan src, ReadO public static unsafe void AddU(ReadOnlySpan src, Span dst, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -907,9 +908,9 @@ public static unsafe void AddU(ReadOnlySpan src, Span dst, int cou public static unsafe void AddSU(ReadOnlySpan src, ReadOnlySpan idx, Span dst, int count) { - fixed (float* psrc = src) - fixed (int* pidx = idx) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (int* pidx = &MemoryMarshal.GetReference(idx)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; int* pIdxCurrent = pidx; @@ -952,9 +953,9 @@ public static unsafe void AddSU(ReadOnlySpan src, ReadOnlySpan idx, public static unsafe void MulElementWiseU(ReadOnlySpan src1, ReadOnlySpan src2, Span dst, int count) { - fixed (float* psrc1 = src1) - fixed (float* psrc2 = src2) - fixed (float* pdst = dst) + fixed (float* psrc1 = &MemoryMarshal.GetReference(src1)) + fixed (float* psrc2 = &MemoryMarshal.GetReference(src2)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrc1Current = psrc1; float* pSrc2Current = psrc2; @@ -1001,7 +1002,7 @@ public static unsafe void MulElementWiseU(ReadOnlySpan src1, ReadOnlySpan public static unsafe float SumU(ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -1039,7 +1040,7 @@ public static unsafe float SumU(ReadOnlySpan src) public static unsafe float SumSqU(ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -1083,7 +1084,7 @@ public static unsafe float SumSqU(ReadOnlySpan src) public static unsafe float SumSqDiffU(float mean, ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -1132,7 +1133,7 @@ public static unsafe float SumSqDiffU(float mean, ReadOnlySpan src) public static unsafe float SumAbsU(ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -1176,7 +1177,7 @@ public static unsafe float SumAbsU(ReadOnlySpan src) public static unsafe float SumAbsDiffU(float mean, ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -1225,7 +1226,7 @@ public static unsafe float SumAbsDiffU(float mean, ReadOnlySpan src) public static unsafe float MaxAbsU(ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -1269,7 +1270,7 @@ public static unsafe float MaxAbsU(ReadOnlySpan src) public static unsafe float MaxAbsDiffU(float mean, ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -1318,8 +1319,8 @@ public static unsafe float MaxAbsDiffU(float mean, ReadOnlySpan src) public static unsafe float DotU(ReadOnlySpan src, ReadOnlySpan dst, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -1373,9 +1374,9 @@ public static unsafe float DotU(ReadOnlySpan src, ReadOnlySpan dst public static unsafe float DotSU(ReadOnlySpan src, ReadOnlySpan dst, ReadOnlySpan idx, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) - fixed (int* pidx = idx) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) + fixed (int* pidx = &MemoryMarshal.GetReference(idx)) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -1430,8 +1431,8 @@ public static unsafe float DotSU(ReadOnlySpan src, ReadOnlySpan ds public static unsafe float Dist2(ReadOnlySpan src, ReadOnlySpan dst, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -1484,9 +1485,9 @@ public static unsafe float Dist2(ReadOnlySpan src, ReadOnlySpan ds public static unsafe void SdcaL1UpdateU(float primalUpdate, int count, ReadOnlySpan src, float threshold, Span v, Span w) { - fixed (float* psrc = src) - fixed (float* pdst1 = v) - fixed (float* pdst2 = w) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst1 = &MemoryMarshal.GetReference(v)) + fixed (float* pdst2 = &MemoryMarshal.GetReference(w)) { float* pSrcEnd = psrc + count; float* pSrcCurrent = psrc; @@ -1546,10 +1547,10 @@ public static unsafe void SdcaL1UpdateU(float primalUpdate, int count, ReadOnlyS public static unsafe void SdcaL1UpdateSU(float primalUpdate, int count, ReadOnlySpan src, ReadOnlySpan indices, float threshold, Span v, Span w) { - fixed (float* psrc = src) - fixed (int* pidx = indices) - fixed (float* pdst1 = v) - fixed (float* pdst2 = w) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (int* pidx = &MemoryMarshal.GetReference(indices)) + fixed (float* pdst1 = &MemoryMarshal.GetReference(v)) + fixed (float* pdst2 = &MemoryMarshal.GetReference(w)) { int* pIdxEnd = pidx + count; float* pSrcCurrent = psrc; diff --git a/src/Microsoft.ML.CpuMath/Sse.cs b/src/Microsoft.ML.CpuMath/Sse.cs index 7bca076b14..3c965ad89f 100644 --- a/src/Microsoft.ML.CpuMath/Sse.cs +++ b/src/Microsoft.ML.CpuMath/Sse.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Runtime.InteropServices; namespace Microsoft.ML.Runtime.Internal.CpuMath { @@ -594,7 +595,7 @@ public static void Add(float a, Span dst) unsafe { - fixed (float* pdst = dst) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) Thunk.AddScalarU(a, pdst, dst.Length); } } @@ -616,7 +617,7 @@ public static void Scale(float a, Span dst) unsafe { - fixed (float* pd = dst) + fixed (float* pd = &MemoryMarshal.GetReference(dst)) Thunk.Scale(a, pd, dst.Length); } } @@ -644,8 +645,8 @@ public static void Scale(float a, ReadOnlySpan src, Span dst, int unsafe { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { Thunk.ScaleSrcU(a, psrc, pdst, count); } @@ -659,7 +660,7 @@ public static void ScaleAdd(float a, float b, Span dst) unsafe { - fixed (float* pdst = dst) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) Thunk.ScaleAddU(a, b, pdst, dst.Length); } } @@ -765,8 +766,8 @@ public static void AddScale(float a, ReadOnlySpan src, Span dst, i unsafe { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) Thunk.AddScaleU(a, psrc, pdst, count); } } @@ -782,9 +783,9 @@ public static void AddScale(float a, ReadOnlySpan src, ReadOnlySpan unsafe { - fixed (float* psrc = src) - fixed (int* pi = indices) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (int* pi = &MemoryMarshal.GetReference(indices)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) Thunk.AddScaleSU(a, psrc, pi, pdst, count); } } @@ -800,9 +801,9 @@ public static void AddScaleCopy(float a, ReadOnlySpan src, ReadOnlySpan src, Span dst, int count) unsafe { - fixed (float* ps = src) - fixed (float* pd = dst) + fixed (float* ps = &MemoryMarshal.GetReference(src)) + fixed (float* pd = &MemoryMarshal.GetReference(dst)) Thunk.AddU(ps, pd, count); } } @@ -868,9 +869,9 @@ public static void Add(ReadOnlySpan src, ReadOnlySpan indices, Span< unsafe { - fixed (float* ps = src) - fixed (int* pi = indices) - fixed (float* pd = dst) + fixed (float* ps = &MemoryMarshal.GetReference(src)) + fixed (int* pi = &MemoryMarshal.GetReference(indices)) + fixed (float* pd = &MemoryMarshal.GetReference(dst)) Thunk.AddSU(ps, pi, pd, count); } } @@ -884,9 +885,9 @@ public static void MulElementWise(ReadOnlySpan src1, ReadOnlySpan Contracts.AssertNonEmpty(dst); unsafe { - fixed (float* ps1 = src1) - fixed (float* ps2 = src2) - fixed (float* pd = dst) + fixed (float* ps1 = &MemoryMarshal.GetReference(src1)) + fixed (float* ps2 = &MemoryMarshal.GetReference(src2)) + fixed (float* pd = &MemoryMarshal.GetReference(dst)) Thunk.MulElementWiseU(ps1, ps2, pd, count); } } @@ -927,7 +928,7 @@ public static float Sum(ReadOnlySpan src) unsafe { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) return Thunk.SumU(psrc, src.Length); } } @@ -938,7 +939,7 @@ public static float SumSq(ReadOnlySpan src) unsafe { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) return Thunk.SumSqU(psrc, src.Length); } } @@ -949,7 +950,7 @@ public static float SumSq(float mean, ReadOnlySpan src) unsafe { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) return (mean == 0 ? Thunk.SumSqU(psrc, src.Length) : Thunk.SumSqDiffU(mean, psrc, src.Length)); } } @@ -960,7 +961,7 @@ public static float SumAbs(ReadOnlySpan src) unsafe { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) return Thunk.SumAbsU(psrc, src.Length); } } @@ -971,7 +972,7 @@ public static float SumAbs(float mean, ReadOnlySpan src) unsafe { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) return (mean == 0 ? Thunk.SumAbsU(psrc, src.Length) : Thunk.SumAbsDiffU(mean, psrc, src.Length)); } } @@ -982,7 +983,7 @@ public static float MaxAbs(ReadOnlySpan src) unsafe { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) return Thunk.MaxAbsU(psrc, src.Length); } } @@ -993,7 +994,7 @@ public static float MaxAbsDiff(float mean, ReadOnlySpan src) unsafe { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) return Thunk.MaxAbsDiffU(mean, psrc, src.Length); } } @@ -1008,8 +1009,8 @@ public static float DotProductDense(ReadOnlySpan a, ReadOnlySpan b unsafe { - fixed (float* pa = a) - fixed (float* pb = b) + fixed (float* pa = &MemoryMarshal.GetReference(a)) + fixed (float* pb = &MemoryMarshal.GetReference(b)) return Thunk.DotU(pa, pb, count); } } @@ -1025,9 +1026,9 @@ public static float DotProductSparse(ReadOnlySpan a, ReadOnlySpan unsafe { - fixed (float* pa = a) - fixed (float* pb = b) - fixed (int* pi = indices) + fixed (float* pa = &MemoryMarshal.GetReference(a)) + fixed (float* pb = &MemoryMarshal.GetReference(b)) + fixed (int* pi = &MemoryMarshal.GetReference(indices)) return Thunk.DotSU(pa, pb, pi, count); } } @@ -1041,8 +1042,8 @@ public static float L2DistSquared(ReadOnlySpan a, ReadOnlySpan b, unsafe { - fixed (float* pa = a) - fixed (float* pb = b) + fixed (float* pa = &MemoryMarshal.GetReference(a)) + fixed (float* pb = &MemoryMarshal.GetReference(b)) return Thunk.Dist2(pa, pb, count); } } @@ -1332,9 +1333,9 @@ public static void SdcaL1UpdateDense(float primalUpdate, int count, ReadOnlySpan unsafe { - fixed (float* psrc = src) - fixed (float* pd1 = v) - fixed (float* pd2 = w) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pd1 = &MemoryMarshal.GetReference(v)) + fixed (float* pd2 = &MemoryMarshal.GetReference(w)) Thunk.SdcaL1UpdateU(primalUpdate, psrc, threshold, pd1, pd2, count); } } @@ -1353,10 +1354,10 @@ public static void SdcaL1UpdateSparse(float primalUpdate, int count, ReadOnlySpa unsafe { - fixed (float* psrc = src) - fixed (int* pi = indices) - fixed (float* pd1 = v) - fixed (float* pd2 = w) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (int* pi = &MemoryMarshal.GetReference(indices)) + fixed (float* pd1 = &MemoryMarshal.GetReference(v)) + fixed (float* pd2 = &MemoryMarshal.GetReference(w)) Thunk.SdcaL1UpdateSU(primalUpdate, psrc, pi, threshold, pd1, pd2, count); } } diff --git a/src/Microsoft.ML.CpuMath/SseIntrinsics.cs b/src/Microsoft.ML.CpuMath/SseIntrinsics.cs index 71b7afcd8f..e84ac5a6ec 100644 --- a/src/Microsoft.ML.CpuMath/SseIntrinsics.cs +++ b/src/Microsoft.ML.CpuMath/SseIntrinsics.cs @@ -15,6 +15,7 @@ using System; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; using nuint = System.UInt64; @@ -427,7 +428,7 @@ public static unsafe void MatMulTranPA(bool add, AlignedArray mat, int[] rgposSr // dst[i] += scale public static unsafe void AddScalarU(float scalar, Span dst) { - fixed (float* pdst = dst) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pDstEnd = pdst + dst.Length; float* pDstCurrent = pdst; @@ -458,7 +459,7 @@ public static unsafe void Scale(float scale, Span dst) { fixed (uint* pLeadingAlignmentMask = &LeadingAlignmentMask[0]) fixed (uint* pTrailingAlignmentMask = &TrailingAlignmentMask[0]) - fixed (float* pd = dst) + fixed (float* pd = &MemoryMarshal.GetReference(dst)) { float* pDstCurrent = pd; int length = dst.Length; @@ -568,8 +569,8 @@ public static unsafe void Scale(float scale, Span dst) public static unsafe void ScaleSrcU(float scale, ReadOnlySpan src, Span dst, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pDstEnd = pdst + count; float* pSrcCurrent = psrc; @@ -602,7 +603,7 @@ public static unsafe void ScaleSrcU(float scale, ReadOnlySpan src, Span dst) { - fixed (float* pdst = dst) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pDstEnd = pdst + dst.Length; float* pDstCurrent = pdst; @@ -634,8 +635,8 @@ public static unsafe void ScaleAddU(float a, float b, Span dst) public static unsafe void AddScaleU(float scale, ReadOnlySpan src, Span dst, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -673,9 +674,9 @@ public static unsafe void AddScaleU(float scale, ReadOnlySpan src, Span src, ReadOnlySpan dst, Span result, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) - fixed (float* pres = result) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) + fixed (float* pres = &MemoryMarshal.GetReference(result)) { float* pResEnd = pres + count; float* pSrcCurrent = psrc; @@ -714,9 +715,9 @@ public static unsafe void AddScaleCopyU(float scale, ReadOnlySpan src, Re public static unsafe void AddScaleSU(float scale, ReadOnlySpan src, ReadOnlySpan idx, Span dst, int count) { - fixed (float* psrc = src) - fixed (int* pidx = idx) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (int* pidx = &MemoryMarshal.GetReference(idx)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; int* pIdxCurrent = pidx; @@ -750,8 +751,8 @@ public static unsafe void AddScaleSU(float scale, ReadOnlySpan src, ReadO public static unsafe void AddU(ReadOnlySpan src, Span dst, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -785,9 +786,9 @@ public static unsafe void AddU(ReadOnlySpan src, Span dst, int cou public static unsafe void AddSU(ReadOnlySpan src, ReadOnlySpan idx, Span dst, int count) { - fixed (float* psrc = src) - fixed (int* pidx = idx) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (int* pidx = &MemoryMarshal.GetReference(idx)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; int* pIdxCurrent = pidx; @@ -818,9 +819,9 @@ public static unsafe void AddSU(ReadOnlySpan src, ReadOnlySpan idx, public static unsafe void MulElementWiseU(ReadOnlySpan src1, ReadOnlySpan src2, Span dst, int count) { - fixed (float* psrc1 = &src1[0]) - fixed (float* psrc2 = &src2[0]) - fixed (float* pdst = dst) + fixed (float* psrc1 = &MemoryMarshal.GetReference(src1)) + fixed (float* psrc2 = &MemoryMarshal.GetReference(src2)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrc1Current = psrc1; float* pSrc2Current = psrc2; @@ -855,7 +856,7 @@ public static unsafe void MulElementWiseU(ReadOnlySpan src1, ReadOnlySpan public static unsafe float SumU(ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -882,7 +883,7 @@ public static unsafe float SumU(ReadOnlySpan src) public static unsafe float SumSqU(ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -913,7 +914,7 @@ public static unsafe float SumSqU(ReadOnlySpan src) public static unsafe float SumSqDiffU(float mean, ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -947,7 +948,7 @@ public static unsafe float SumSqDiffU(float mean, ReadOnlySpan src) public static unsafe float SumAbsU(ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -978,7 +979,7 @@ public static unsafe float SumAbsU(ReadOnlySpan src) public static unsafe float SumAbsDiffU(float mean, ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -1012,7 +1013,7 @@ public static unsafe float SumAbsDiffU(float mean, ReadOnlySpan src) public static unsafe float MaxAbsU(ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -1043,7 +1044,7 @@ public static unsafe float MaxAbsU(ReadOnlySpan src) public static unsafe float MaxAbsDiffU(float mean, ReadOnlySpan src) { - fixed (float* psrc = src) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) { float* pSrcEnd = psrc + src.Length; float* pSrcCurrent = psrc; @@ -1077,8 +1078,8 @@ public static unsafe float MaxAbsDiffU(float mean, ReadOnlySpan src) public static unsafe float DotU(ReadOnlySpan src, ReadOnlySpan dst, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -1116,9 +1117,9 @@ public static unsafe float DotU(ReadOnlySpan src, ReadOnlySpan dst public static unsafe float DotSU(ReadOnlySpan src, ReadOnlySpan dst, ReadOnlySpan idx, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) - fixed (int* pidx = idx) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) + fixed (int* pidx = &MemoryMarshal.GetReference(idx)) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -1157,8 +1158,8 @@ public static unsafe float DotSU(ReadOnlySpan src, ReadOnlySpan ds public static unsafe float Dist2(ReadOnlySpan src, ReadOnlySpan dst, int count) { - fixed (float* psrc = src) - fixed (float* pdst = dst) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst = &MemoryMarshal.GetReference(dst)) { float* pSrcCurrent = psrc; float* pDstCurrent = pdst; @@ -1195,9 +1196,9 @@ public static unsafe float Dist2(ReadOnlySpan src, ReadOnlySpan ds public static unsafe void SdcaL1UpdateU(float primalUpdate, int count, ReadOnlySpan src, float threshold, Span v, Span w) { - fixed (float* psrc = src) - fixed (float* pdst1 = v) - fixed (float* pdst2 = w) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (float* pdst1 = &MemoryMarshal.GetReference(v)) + fixed (float* pdst2 = &MemoryMarshal.GetReference(w)) { float* pSrcEnd = psrc + count; float* pSrcCurrent = psrc; @@ -1240,10 +1241,10 @@ public static unsafe void SdcaL1UpdateU(float primalUpdate, int count, ReadOnlyS public static unsafe void SdcaL1UpdateSU(float primalUpdate, int count, ReadOnlySpan src, ReadOnlySpan indices, float threshold, Span v, Span w) { - fixed (float* psrc = src) - fixed (int* pidx = indices) - fixed (float* pdst1 = v) - fixed (float* pdst2 = w) + fixed (float* psrc = &MemoryMarshal.GetReference(src)) + fixed (int* pidx = &MemoryMarshal.GetReference(indices)) + fixed (float* pdst1 = &MemoryMarshal.GetReference(v)) + fixed (float* pdst2 = &MemoryMarshal.GetReference(w)) { int* pIdxEnd = pidx + count; float* pSrcCurrent = psrc; From 1d1d758364c5969b1dff6a349f01e99acff41fe7 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 15 Oct 2018 13:29:32 -0500 Subject: [PATCH 3/3] PR feedback --- src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj b/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj index 9fe8615a8c..f9d3d90b59 100644 --- a/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj +++ b/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj @@ -28,6 +28,7 @@ +