diff --git a/src/Microsoft.ML.Core/BestFriendAttribute.cs b/src/Microsoft.ML.Core/BestFriendAttribute.cs
index e73c10e241..1470f95c34 100644
--- a/src/Microsoft.ML.Core/BestFriendAttribute.cs
+++ b/src/Microsoft.ML.Core/BestFriendAttribute.cs
@@ -4,7 +4,13 @@
using System;
+#if CPUMATH_INFRASTRUCTURE
+// CpuMath has its own BestFriend and WantsToBeBestFriends attributes for making itself a standalone module
+namespace Microsoft.ML.Runtime.Internal.CpuMath.Core
+#else
+// This namespace contains the BestFriend and WantsToBeBestFriends attributes generally used in ML.NET project settings
namespace Microsoft.ML
+#endif
{
///
/// Intended to be applied to types and members marked as internal to indicate that friend access of this
diff --git a/src/Microsoft.ML.Core/Microsoft.ML.Core.csproj b/src/Microsoft.ML.Core/Microsoft.ML.Core.csproj
index b41d089d03..a672faca77 100644
--- a/src/Microsoft.ML.Core/Microsoft.ML.Core.csproj
+++ b/src/Microsoft.ML.Core/Microsoft.ML.Core.csproj
@@ -8,10 +8,6 @@
Microsoft.ML
-
-
-
-
diff --git a/src/Microsoft.ML.Core/Properties/AssemblyInfo.cs b/src/Microsoft.ML.Core/Properties/AssemblyInfo.cs
index aaa44a6bc7..a61e96ce7b 100644
--- a/src/Microsoft.ML.Core/Properties/AssemblyInfo.cs
+++ b/src/Microsoft.ML.Core/Properties/AssemblyInfo.cs
@@ -40,13 +40,3 @@
[assembly: InternalsVisibleTo(assemblyName: "Microsoft.ML.Transforms" + PublicKey.Value)]
[assembly: WantsToBeBestFriends]
-
-namespace Microsoft.ML
-{
- [BestFriend]
- internal static class PublicKey
- {
- public const string Value = ", PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb";
- public const string TestValue = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4";
- }
-}
diff --git a/src/Microsoft.ML.Core/PublicKey.cs b/src/Microsoft.ML.Core/PublicKey.cs
new file mode 100644
index 0000000000..9a944c3d18
--- /dev/null
+++ b/src/Microsoft.ML.Core/PublicKey.cs
@@ -0,0 +1,20 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#if !CPUMATH_INFRASTRUCTURE
+// This namespace contains the PublicKey generally used in ML.NET project settings
+namespace Microsoft.ML
+#else
+// CpuMath module has its own PublicKey for isolating itself from Microsoft.ML.Core
+// Note that CpuMath uses its own BestFriend defined in Microsoft.ML.Runtime.Internal.CpuMath.Core.
+namespace Microsoft.ML.Runtime.Internal.CpuMath.Core
+#endif
+{
+ [BestFriend]
+ internal static class PublicKey
+ {
+ public const string Value = ", PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb";
+ public const string TestValue = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010015c01ae1f50e8cc09ba9eac9147cf8fd9fce2cfe9f8dce4f7301c4132ca9fb50ce8cbf1df4dc18dd4d210e4345c744ecb3365ed327efdbc52603faa5e21daa11234c8c4a73e51f03bf192544581ebe107adee3a34928e39d04e524a9ce729d5090bfd7dad9d10c722c0def9ccc08ff0a03790e48bcd1f9b6c476063e1966a1c4";
+ }
+}
diff --git a/src/Microsoft.ML.Core/Utilities/Contracts.cs b/src/Microsoft.ML.Core/Utilities/Contracts.cs
index 67f559d2fb..d567d6e883 100644
--- a/src/Microsoft.ML.Core/Utilities/Contracts.cs
+++ b/src/Microsoft.ML.Core/Utilities/Contracts.cs
@@ -16,7 +16,11 @@
using System.IO;
using System.Threading;
+#if CPUMATH_INFRASTRUCTURE
+namespace Microsoft.ML.Runtime.Internal.CpuMath.Core
+#else
namespace Microsoft.ML.Runtime
+#endif
{
using Conditional = System.Diagnostics.ConditionalAttribute;
using Debug = System.Diagnostics.Debug;
@@ -27,7 +31,11 @@ namespace Microsoft.ML.Runtime
/// totally replace the exception, etc. It is not legal to return null from
/// Process (unless null was passed in, which really shouldn't happen).
///
+#if CPUMATH_INFRASTRUCTURE
+ internal interface IExceptionContext
+#else
public interface IExceptionContext
+#endif
{
TException Process(TException ex)
where TException : Exception;
@@ -38,6 +46,15 @@ TException Process(TException ex)
string ContextDescription { get; }
}
+#if CPUMATH_INFRASTRUCTURE
+ [Flags]
+ internal enum MessageSensitivity
+ {
+ None = 0,
+ Unknown = ~None
+ }
+#endif
+
[BestFriend]
internal static partial class Contracts
{
@@ -137,6 +154,7 @@ public static MessageSensitivity Sensitivity(this Exception ex)
return (ex.Data[SensitivityKey] as MessageSensitivity?) ?? MessageSensitivity.Unknown;
}
+#if !CPUMATH_INFRASTRUCTURE
///
/// This is an internal convenience implementation of an exception context to make marking
/// exceptions with a specific sensitivity flag a bit less onorous. The alternative to a scheme
@@ -213,6 +231,7 @@ public static IExceptionContext UserSensitive(this IExceptionContext ctx)
///
public static IExceptionContext SchemaSensitive(this IExceptionContext ctx)
=> new SensitiveExceptionContext(ctx, MessageSensitivity.Schema);
+#endif
///
/// Sets the assert handler to the given function, returning the previous handler.
@@ -721,6 +740,7 @@ public static void CheckIO(this IExceptionContext ctx, bool f, string msg)
throw ExceptIO(ctx, msg);
}
+#if !CPUMATH_INFRASTRUCTURE
///
/// Check state of the host and throw exception if host marked to stop all exection.
///
@@ -729,6 +749,7 @@ public static void CheckAlive(this IHostEnvironment env)
if (env.IsCancelled)
throw Process(new OperationCanceledException("Operation was cancelled."), env);
}
+#endif
///
/// This documents that the parameter can legally be null.
diff --git a/src/Microsoft.ML.CpuMath/AlignedArray.cs b/src/Microsoft.ML.CpuMath/AlignedArray.cs
index cfbee22eab..4602e884e4 100644
--- a/src/Microsoft.ML.CpuMath/AlignedArray.cs
+++ b/src/Microsoft.ML.CpuMath/AlignedArray.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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System;
namespace Microsoft.ML.Runtime.Internal.CpuMath
diff --git a/src/Microsoft.ML.CpuMath/AlignedMatrix.cs b/src/Microsoft.ML.CpuMath/AlignedMatrix.cs
index 5412e5fd77..6d550fc3fc 100644
--- a/src/Microsoft.ML.CpuMath/AlignedMatrix.cs
+++ b/src/Microsoft.ML.CpuMath/AlignedMatrix.cs
@@ -4,6 +4,7 @@
using Float = System.Single;
+using Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System;
using System.Collections;
using System.Collections.Generic;
diff --git a/src/Microsoft.ML.CpuMath/AssemblyInfo.cs b/src/Microsoft.ML.CpuMath/AssemblyInfo.cs
index 17bdf84324..7710703c29 100644
--- a/src/Microsoft.ML.CpuMath/AssemblyInfo.cs
+++ b/src/Microsoft.ML.CpuMath/AssemblyInfo.cs
@@ -2,8 +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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System.Runtime.CompilerServices;
-using Microsoft.ML;
[assembly: InternalsVisibleTo("Microsoft.ML.CpuMath.UnitTests.netstandard" + PublicKey.TestValue)]
[assembly: InternalsVisibleTo("Microsoft.ML.CpuMath.UnitTests.netcoreapp" + PublicKey.TestValue)]
diff --git a/src/Microsoft.ML.CpuMath/CpuAligenedMathUtils.cs b/src/Microsoft.ML.CpuMath/CpuAligenedMathUtils.cs
index d4c8e8e087..33690055b2 100644
--- a/src/Microsoft.ML.CpuMath/CpuAligenedMathUtils.cs
+++ b/src/Microsoft.ML.CpuMath/CpuAligenedMathUtils.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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
+
namespace Microsoft.ML.Runtime.Internal.CpuMath
{
[BestFriend]
diff --git a/src/Microsoft.ML.CpuMath/CpuMathUtils.netcoreapp.cs b/src/Microsoft.ML.CpuMath/CpuMathUtils.netcoreapp.cs
index ed5be5390a..d895e590a9 100644
--- a/src/Microsoft.ML.CpuMath/CpuMathUtils.netcoreapp.cs
+++ b/src/Microsoft.ML.CpuMath/CpuMathUtils.netcoreapp.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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics.X86;
using System;
diff --git a/src/Microsoft.ML.CpuMath/CpuMathUtils.netstandard.cs b/src/Microsoft.ML.CpuMath/CpuMathUtils.netstandard.cs
index b3f46f0a5a..5ecbc62be1 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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System;
using System.Runtime.CompilerServices;
diff --git a/src/Microsoft.ML.CpuMath/EigenUtils.cs b/src/Microsoft.ML.CpuMath/EigenUtils.cs
index fc20b8bfe7..cff9d1b32d 100644
--- a/src/Microsoft.ML.CpuMath/EigenUtils.cs
+++ b/src/Microsoft.ML.CpuMath/EigenUtils.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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System;
using Float = System.Single;
diff --git a/src/Microsoft.ML.CpuMath/ICpuBuffer.cs b/src/Microsoft.ML.CpuMath/ICpuBuffer.cs
index 7f0c0e8126..a121351cff 100644
--- a/src/Microsoft.ML.CpuMath/ICpuBuffer.cs
+++ b/src/Microsoft.ML.CpuMath/ICpuBuffer.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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System;
using System.Collections.Generic;
using Float = System.Single;
diff --git a/src/Microsoft.ML.CpuMath/IntUtils.cs b/src/Microsoft.ML.CpuMath/IntUtils.cs
index cec2b71dfb..dbb07e31cb 100644
--- a/src/Microsoft.ML.CpuMath/IntUtils.cs
+++ b/src/Microsoft.ML.CpuMath/IntUtils.cs
@@ -2,7 +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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Security;
diff --git a/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj b/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj
index 8fa97116ba..938b2b2d5a 100644
--- a/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj
+++ b/src/Microsoft.ML.CpuMath/Microsoft.ML.CpuMath.csproj
@@ -5,11 +5,17 @@
netstandard2.0;netcoreapp3.0
Microsoft.ML.CpuMath
true
+ $(DefineConstants);CPUMATH_INFRASTRUCTURE
7.3
-
+
+
+
+
+
+
@@ -24,8 +30,4 @@
-
-
-
-
diff --git a/src/Microsoft.ML.CpuMath/ProbabilityFunctions.cs b/src/Microsoft.ML.CpuMath/ProbabilityFunctions.cs
index ed1208c80c..64875bb8b6 100644
--- a/src/Microsoft.ML.CpuMath/ProbabilityFunctions.cs
+++ b/src/Microsoft.ML.CpuMath/ProbabilityFunctions.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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System;
namespace Microsoft.ML.Runtime.Internal.CpuMath
diff --git a/src/Microsoft.ML.CpuMath/Sse.cs b/src/Microsoft.ML.CpuMath/Sse.cs
index b3f00d1136..8b1c4da70f 100644
--- a/src/Microsoft.ML.CpuMath/Sse.cs
+++ b/src/Microsoft.ML.CpuMath/Sse.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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System;
using System.Runtime.InteropServices;
diff --git a/src/Microsoft.ML.CpuMath/Thunk.cs b/src/Microsoft.ML.CpuMath/Thunk.cs
index faf0b82c66..8ff725b54a 100644
--- a/src/Microsoft.ML.CpuMath/Thunk.cs
+++ b/src/Microsoft.ML.CpuMath/Thunk.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 Microsoft.ML.Runtime.Internal.CpuMath.Core;
using System.Runtime.InteropServices;
using System.Security;
diff --git a/tools-local/Microsoft.ML.InternalCodeAnalyzer/BestFriendAnalyzer.cs b/tools-local/Microsoft.ML.InternalCodeAnalyzer/BestFriendAnalyzer.cs
index 1adc735b25..98066222b3 100644
--- a/tools-local/Microsoft.ML.InternalCodeAnalyzer/BestFriendAnalyzer.cs
+++ b/tools-local/Microsoft.ML.InternalCodeAnalyzer/BestFriendAnalyzer.cs
@@ -41,17 +41,17 @@ public override void Initialize(AnalysisContext context)
context.RegisterSemanticModelAction(Analyze);
}
- private void Analyze(SemanticModelAnalysisContext context)
+ private void AnalyzeCore(SemanticModelAnalysisContext context, string attributeName, string assemblyAttributeName)
{
var model = context.SemanticModel;
var comp = model.Compilation;
// Get the symbols of the key types we are analyzing. If we can't find either
// of them there is no point in going further.
- var bestFriendAttributeType = comp.GetTypeByMetadataName(AttributeName);
+ var bestFriendAttributeType = comp.GetTypeByMetadataName(attributeName);
if (bestFriendAttributeType == null)
return;
- var wantsToBeBestFriendsAttributeType = comp.GetTypeByMetadataName(AssemblyAttributeName);
+ var wantsToBeBestFriendsAttributeType = comp.GetTypeByMetadataName(assemblyAttributeName);
if (wantsToBeBestFriendsAttributeType == null)
return;
@@ -89,6 +89,9 @@ private void Analyze(SemanticModelAnalysisContext context)
// further.
if (!assemblyHasAttrMap.TryGetValue(symbolAssembly, out bool assemblyWantsBestFriends))
{
+ // It's the first of seeing the assembly containing symbol. A key-value pair is added into assemblyHasAttrMap to
+ // indicate if that assembly includes an attribute WantsToBeBestFriends. If an assembly has WantsToBeBestFriends then
+ // its associated value would be true.
assemblyWantsBestFriends = symbolAssembly.GetAttributes().Any(a => a.AttributeClass == wantsToBeBestFriendsAttributeType);
assemblyHasAttrMap[symbolAssembly] = assemblyWantsBestFriends;
}
@@ -104,5 +107,11 @@ private void Analyze(SemanticModelAnalysisContext context)
context.ReportDiagnostic(diagnostic);
}
}
+
+ private void Analyze(SemanticModelAnalysisContext context)
+ {
+ AnalyzeCore(context, "Microsoft.ML.BestFriendAttribute", "Microsoft.ML.WantsToBeBestFriendsAttribute");
+ AnalyzeCore(context, "Microsoft.ML.Runtime.Internal.CpuMath.Core.BestFriendAttribute", "Microsoft.ML.Runtime.Internal.CpuMath.Core.WantsToBeBestFriendsAttribute");
+ }
}
}
diff --git a/tools-local/Microsoft.ML.InternalCodeAnalyzer/ContractsCheckAnalyzer.cs b/tools-local/Microsoft.ML.InternalCodeAnalyzer/ContractsCheckAnalyzer.cs
index 6143d7386b..6328a7cf5f 100644
--- a/tools-local/Microsoft.ML.InternalCodeAnalyzer/ContractsCheckAnalyzer.cs
+++ b/tools-local/Microsoft.ML.InternalCodeAnalyzer/ContractsCheckAnalyzer.cs
@@ -196,8 +196,10 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
var containingSymbolName = methodSymbol.ContainingSymbol.ToString();
// The "internal" version is one used by some projects that want to benefit from Contracts,
// but for some reason cannot reference MLCore.
+ // Contract functions defined Microsoft.ML.Runtime.Internal.CpuMath.Core are introduced for breaking the dependencies
+ // from CpuMath project to Microsoft.ML.Core.
if (containingSymbolName != "Microsoft.ML.Runtime.Contracts" &&
- containingSymbolName != "Microsoft.ML.Runtime.Internal.Contracts")
+ containingSymbolName != "Microsoft.ML.Runtime.Internal.CpuMath.Core.Contracts")
{
return;
}