forked from tsai/mathnet-numerics
3 changed files with 220 additions and 120 deletions
@ -1,119 +0,0 @@ |
|||
(*** hide ***) |
|||
#I "../../out/lib/net40" |
|||
#r "MathNet.Numerics.dll" |
|||
#r "MathNet.Numerics.FSharp.dll" |
|||
|
|||
(** |
|||
Intel Math Kernel Library (MKL) |
|||
=============================== |
|||
|
|||
Math.NET Numerics is designed such that performance-sensitive algorithms |
|||
can be swapped with alternative implementations by the concept of providers. |
|||
There is currently only a provider for linear algebra related routines, but there |
|||
are plans to add additional ones e.g. related to nonlinear optimization problems or signal processing. |
|||
|
|||
Providers become interesting when they can leverage a platform-native high performance library |
|||
like Intel MKL instead of the default purely managed provider. Math.NET Numerics |
|||
provides such a provider in the form of two NuGet packages: |
|||
|
|||
* MathNet.Numerics.MKL.Win-x86 |
|||
* MathNet.Numerics.MKL.Win-x64 |
|||
|
|||
Equivalent providers for Linux can be built manually from source. |
|||
|
|||
In order to leverage the MKL linear algebra provider, reference the appropriate NuGet package |
|||
in your project. Set "Copy to Output Directory" for both MathNet.Numerics.MKL.dll and libiomp5md.dll |
|||
to "Copy always", or place the two native DLLs manually into the same directory as your application's executable. |
|||
Then enable it by calling: |
|||
|
|||
[lang=csharp] |
|||
Control.UseNativeMKL(); |
|||
|
|||
Alternatively you can also enable it by setting the environment variable `MathNetNumericsLAProvider=MKL`. |
|||
|
|||
You can also explicitly disable the MKL provider by forcing it to use the managed provider by calling: |
|||
|
|||
[lang=csharp] |
|||
Control.UseManaged(); |
|||
|
|||
|
|||
Using Intel MKL on Linux with Mono |
|||
---------------------------------- |
|||
|
|||
We no longer provide new MKL NuGet packages for Linux since we no longer have an license to do so |
|||
(only Windows for now), but it is still possible to use the older Linux MKL NuGet packages if you |
|||
don't want to build it yourself. Assuming you have Mono and NuGet installed (here v3.2.8), you can |
|||
fetch the MKL package of the right architecture (x64 or x86, `uname -m` if you don't know) as usual: |
|||
|
|||
[lang=sh] |
|||
mono nuget.exe install MathNet.Numerics -Pre -OutputDirectory packages |
|||
mono nuget.exe install MathNet.Numerics.MKL.Linux-x64 -Pre -OutputDirectory packages |
|||
|
|||
Native assembly resolving is very different on Linux than on Windows, simply putting the native |
|||
libraries into the same folder as the executable is not enough. The safe way is to edit `/etc/ld.so.conf` |
|||
and use `ldconfig` to tell where to look for the libraries, but for now we'll just copy them to `/usr/lib`: |
|||
|
|||
[lang=sh] |
|||
sudo cp packages/MathNet.Numerics.MKL.Linux-x64.1.3.0/content/libiomp5.so /usr/lib/ |
|||
sudo cp packages/MathNet.Numerics.MKL.Linux-x64.1.3.0/content/MathNet.Numerics.MKL.dll /usr/lib/ |
|||
|
|||
Then we're all set and can just call `Control.UseNativeMKL()` if we want to use the native provider. |
|||
Let's create the following C# file `Example.cs`: |
|||
|
|||
[lang=csharp] |
|||
using System; |
|||
using System.Diagnostics; |
|||
using MathNet.Numerics; |
|||
using MathNet.Numerics.LinearAlgebra; |
|||
|
|||
class Program |
|||
{ |
|||
static void Main(string[] args) |
|||
{ |
|||
// Using managed code only |
|||
Control.UseManaged(); |
|||
Console.WriteLine(Control.LinearAlgebraProvider); |
|||
|
|||
var m = Matrix<double>.Build.Random(500, 500); |
|||
var v = Vector<double>.Build.Random(500); |
|||
|
|||
var w = Stopwatch.StartNew(); |
|||
var y1 = m.Solve(v); |
|||
Console.WriteLine(w.Elapsed); |
|||
Console.WriteLine(y1); |
|||
|
|||
// Using the Intel MKL native provider |
|||
Control.UseNativeMKL(); |
|||
Console.WriteLine(Control.LinearAlgebraProvider); |
|||
|
|||
w.Restart(); |
|||
var y2 = m.Solve(v); |
|||
Console.WriteLine(w.Elapsed); |
|||
Console.WriteLine(y2); |
|||
} |
|||
} |
|||
|
|||
Compile and run: |
|||
|
|||
[lang=sh] |
|||
# single line: |
|||
mcs -optimize -lib:packages/MathNet.Numerics.3.0.0-alpha8/lib/net40/ |
|||
-r:MathNet.Numerics.dll Example.cs -out:Example |
|||
# launch: |
|||
mono Example |
|||
|
|||
|
|||
Licensing Restrictions |
|||
---------------------- |
|||
|
|||
Be aware that unlike the core of Math.NET Numerics including the native wrapper, which are both |
|||
open source under the terms of the MIT/X11 license, the Intel MKL binaries themselves are closed |
|||
source and non-free. |
|||
|
|||
The Math.NET Numerics project does own an Intel MKL license (for Windows, no longer for Linux) and |
|||
thus does have the right to distribute it along Math.NET Numerics. You can therefore use the Math.NET |
|||
Numerics MKL native provider for free for your own use. However, it does *not* give you any right to |
|||
redistribute it again yourself to customers of your own product. **If you need to redistribute, |
|||
buy a license from Intel. If unsure, contact the Intel sales team to clarify.** |
|||
|
|||
*) |
|||
@ -0,0 +1,219 @@ |
|||
Intel Math Kernel Library (MKL) |
|||
=============================== |
|||
|
|||
Math.NET Numerics is designed such that performance-sensitive algorithms |
|||
can be swapped with alternative implementations by the concept of providers. |
|||
There is currently only a provider for linear algebra related routines, but there |
|||
are plans to add additional more e.g. related to nonlinear optimization problems or signal processing. |
|||
|
|||
Providers become interesting when they can leverage a platform-native high performance library |
|||
like Intel MKL instead of the default purely managed provider. Math.NET Numerics |
|||
provides such a provider as NuGet packages: |
|||
|
|||
* MathNet.Numerics.MKL.Win |
|||
* MathNet.Numerics.MKL.Linux |
|||
|
|||
Since these native libraries can become very big, there are also variants supporting |
|||
only a single platform, for example: |
|||
|
|||
* MathNet.Numerics.MKL.Win-x86 |
|||
* MathNet.Numerics.MKL.Win-x64 |
|||
|
|||
In order to leverage the MKL linear algebra provider, we need to make sure the .NET |
|||
runtime can find the native libraries (see below) and then enable it by calling: |
|||
|
|||
[lang=csharp] |
|||
Control.UseNativeMKL(); |
|||
|
|||
Alternatively you can also enable it by setting the environment variable `MathNetNumericsLAProvider=MKL`. |
|||
|
|||
You can also explicitly disable the MKL provider by forcing it to use the managed provider by calling: |
|||
|
|||
[lang=csharp] |
|||
Control.UseManaged(); |
|||
|
|||
You can tell what provider is effectively loaded by calling `Control.LinearAlgebraProvider.ToString()`, |
|||
which will return something along the lines of `Intel MKL (x86; revision 7)`. |
|||
|
|||
|
|||
Native Binaries |
|||
--------------- |
|||
|
|||
Native binaries like the MKL provider are platform specific and we need to load |
|||
them into the executing process with services of the platform, not of the .Net Runtime. |
|||
We use P/Invoke to talk to the binaries, but for this to work they must |
|||
have already been loaded or the platform needs a way to find them, which works |
|||
very different to how the .Net Runtime finds referenced assemblies (called "Fusion"). |
|||
|
|||
Since v3.6.0 the following directories are probed in order for the expected binary: |
|||
|
|||
1. If `Control.NativeProviderPath` is set: `{NativeProviderPath}/{Platform}/` |
|||
2. If `Control.NativeProviderPath` is set: `{NativeProviderPath}/` |
|||
3. `{AppDomain.BaseDirectory}/{Platform}/` |
|||
4. `{AppDomain.BaseDirectory}/` |
|||
5. `{ExecutingAssemblyPath}/{Platform}/` |
|||
6. `{ExecutingAssemblyPath}/` |
|||
7. Fall back to the platform's default behavior (see below) |
|||
|
|||
Where `{Platform}` can be one of the following: `x86`, `x64`, `ia64`, `arm` or `arm64`. |
|||
|
|||
This means that you can place the MKL provider binaries e.g. into `C:\MKL\x86` |
|||
and `C:\MKL\x64` for the 32 and 64 bit builds, and then set `Control.NativeProviderPath = @"C:\MKL";`. |
|||
It will automatically choose the right one depending on whether your process is |
|||
running in 32 or 64 bit mode. No more need to copy these large binaries to every project. |
|||
|
|||
|
|||
Default Behavior on Windows |
|||
--------------------------- |
|||
|
|||
On Windows it is usually enough to make sure the native libraries are in the |
|||
same folder as the executable. Reference the appropriate NuGet package and set |
|||
"Copy to Output Directory" for both MathNet.Numerics.MKL.dll and libiomp5md.dll |
|||
to "Copy always", or place the two native DLLs manually into the same directory |
|||
as your application's executable. There is no need to set the native provider |
|||
path explicitly. |
|||
|
|||
For more details how the platform default behavior works and what influences it, |
|||
see [Dynamic-Link Library Search Order](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586.aspx). |
|||
|
|||
|
|||
Default Behavior on Linux |
|||
------------------------- |
|||
|
|||
Native assembly resolving is very different on Linux than on Windows, simply putting the native |
|||
libraries into the same folder as the executable is not enough. The safe way is to edit `/etc/ld.so.conf` |
|||
and use `ldconfig` to tell where to look for the libraries. Alternatively you could add the path |
|||
to `LD_LIBRARY_PATH` or even just copy them to `/usr/lib`. |
|||
|
|||
For details see Mono's [Interop with Native Libraries](http://www.mono-project.com/docs/advanced/pinvoke/#linux-shared-library-search-path). |
|||
|
|||
|
|||
Default Behavior on Mac OS X |
|||
---------------------------- |
|||
|
|||
You can configure the search path on one of the environment variables like `DYLD_LIBRARY_PATH` |
|||
or just copy them e.g. to `/usr/lib`. |
|||
|
|||
For details see Mono's [Interop with Native Libraries](http://www.mono-project.com/docs/advanced/pinvoke/#mac-os-x-framework-and-dylib-search-path). |
|||
|
|||
|
|||
F# Interactive |
|||
-------------- |
|||
|
|||
If you're working from within VisualStudio with an F# project, you can NuGet-reference both |
|||
`MathNet.Numerics.FSharp` and `MathNet.Numerics.MKL.Win-x64` (provided you have configured it to run |
|||
as 64 bit process, see `System.Environment.Is64BitProcess` to find out). VisualStudio with the F# |
|||
power tools installed then offers in the context menu to generated reference scripts for F# Interactive. |
|||
These will not include the native binaries out of the box, but you can go from there by extending |
|||
`load-references.fsx` as follows: |
|||
|
|||
[lang=fsharp] |
|||
open System.IO |
|||
open MathNet.Numerics |
|||
|
|||
Control.NativeProviderPath <- Path.Combine(__SOURCE_DIRECTORY__,"../") |
|||
Control.UseNativeMKL() |
|||
|
|||
This will work provided the MKL NuGet package will copy the native binaries to the root directory |
|||
and the generated load script is located in the Scripts subfolder. |
|||
|
|||
Alternatively just copy the native providers to a shared directory and use them |
|||
directly from there, without referencing the MKL NuGet package separately, |
|||
and execute something along the lines of: |
|||
|
|||
[lang=fsharp] |
|||
Control.NativeProviderPath <- @"C:\MKL" |
|||
Control.UseNativeMKL() |
|||
|
|||
See also [Loading Native DLLs in F# Interactive](http://christoph.ruegg.name/blog/loading-native-dlls-in-fsharp-interactive.html) |
|||
for more alternatives. |
|||
|
|||
LINQPad and assembly shadowing |
|||
------------------------------ |
|||
|
|||
The automatic strategy may still work if assembly shadowing is involved, |
|||
but it often simpler and more reliable to provide the folder explicitly. |
|||
This also works well in LINQPad, with and without assembly shadowing: |
|||
|
|||
[lang=csharp] |
|||
Control.NativeProviderPath = @"C:\MKL"; |
|||
Control.UseNativeMKL(); |
|||
|
|||
|
|||
Example: Intel MKL on Linux with Mono |
|||
------------------------------------- |
|||
|
|||
We also provide MKL NuGet package for Linux if you do not want to build them yourself. Assuming you have |
|||
Mono and NuGet installed (here v3.2.8), you can fetch the MKL package of the right architecture |
|||
(x64 or x86, `uname -m` if you don't know) as usual: |
|||
|
|||
[lang=sh] |
|||
mono nuget.exe install MathNet.Numerics -Pre -OutputDirectory packages |
|||
mono nuget.exe install MathNet.Numerics.MKL.Linux-x64 -Pre -OutputDirectory packages |
|||
|
|||
Native assembly resolving is very different on Linux than on Windows, simply putting the native |
|||
libraries into the same folder as the executable is not enough. The safe way is to edit `/etc/ld.so.conf` |
|||
and use `ldconfig` to tell where to look for the libraries, but for now we'll just copy them to `/usr/lib`: |
|||
|
|||
[lang=sh] |
|||
sudo cp packages/MathNet.Numerics.MKL.Linux-x64.1.3.0/content/libiomp5.so /usr/lib/ |
|||
sudo cp packages/MathNet.Numerics.MKL.Linux-x64.1.3.0/content/MathNet.Numerics.MKL.dll /usr/lib/ |
|||
|
|||
Then we're all set and can just call `Control.UseNativeMKL()` if we want to use the native provider. |
|||
Let's create the following C# file `Example.cs`: |
|||
|
|||
[lang=csharp] |
|||
using System; |
|||
using System.Diagnostics; |
|||
using MathNet.Numerics; |
|||
using MathNet.Numerics.LinearAlgebra; |
|||
|
|||
class Program |
|||
{ |
|||
static void Main(string[] args) |
|||
{ |
|||
// Using managed code only |
|||
Control.UseManaged(); |
|||
Console.WriteLine(Control.LinearAlgebraProvider); |
|||
|
|||
var m = Matrix<double>.Build.Random(500, 500); |
|||
var v = Vector<double>.Build.Random(500); |
|||
|
|||
var w = Stopwatch.StartNew(); |
|||
var y1 = m.Solve(v); |
|||
Console.WriteLine(w.Elapsed); |
|||
Console.WriteLine(y1); |
|||
|
|||
// Using the Intel MKL native provider |
|||
Control.UseNativeMKL(); |
|||
Console.WriteLine(Control.LinearAlgebraProvider); |
|||
|
|||
w.Restart(); |
|||
var y2 = m.Solve(v); |
|||
Console.WriteLine(w.Elapsed); |
|||
Console.WriteLine(y2); |
|||
} |
|||
} |
|||
|
|||
Compile and run: |
|||
|
|||
[lang=sh] |
|||
# single line: |
|||
mcs -optimize -lib:packages/MathNet.Numerics.3.0.0-alpha8/lib/net40/ |
|||
-r:MathNet.Numerics.dll Example.cs -out:Example |
|||
# launch: |
|||
mono Example |
|||
|
|||
|
|||
Licensing Restrictions |
|||
---------------------- |
|||
|
|||
Be aware that unlike the core of Math.NET Numerics including the native wrapper, which are both |
|||
open source under the terms of the MIT/X11 license, the Intel MKL binaries themselves are closed |
|||
source and non-free. |
|||
|
|||
The Math.NET Numerics project does own an Intel MKL license (for Windows, no longer for Linux) and |
|||
thus does have the right to distribute it along Math.NET Numerics. You can therefore use the Math.NET |
|||
Numerics MKL native provider for free for your own use. However, it does *not* give you any right to |
|||
redistribute it again yourself to customers of your own product. **If you need to redistribute, |
|||
buy a license from Intel. If unsure, contact the Intel sales team to clarify.** |
|||
Loading…
Reference in new issue