diff --git a/MathNet.Numerics.All.sln.DotSettings b/MathNet.Numerics.All.sln.DotSettings index 29ce644d..c01d39b4 100644 --- a/MathNet.Numerics.All.sln.DotSettings +++ b/MathNet.Numerics.All.sln.DotSettings @@ -71,5 +71,6 @@ OTHER DEALINGS IN THE SOFTWARE. TFQMR WH True + True <data /> <data><IncludeFilters /><ExcludeFilters /></data> \ No newline at end of file diff --git a/MathNet.Numerics.sln.DotSettings b/MathNet.Numerics.sln.DotSettings index ba81b902..6cec424b 100644 --- a/MathNet.Numerics.sln.DotSettings +++ b/MathNet.Numerics.sln.DotSettings @@ -103,6 +103,7 @@ OTHER DEALINGS IN THE SOFTWARE. TFQMR WH True + True <data /> <data><IncludeFilters /><ExcludeFilters /></data> \ No newline at end of file diff --git a/src/NativeProviders/Linux/mkl_build.sh b/src/NativeProviders/Linux/mkl_build.sh index 3cc7b1aa..391abfe1 100644 --- a/src/NativeProviders/Linux/mkl_build.sh +++ b/src/NativeProviders/Linux/mkl_build.sh @@ -1,11 +1,16 @@ +#Note: g++ multilib must be installed export INTEL=/opt/intel export MKL=$INTEL/mkl export OPENMP=$INTEL/composerxe/lib +export OUT=../../../out/MKL/Linux -g++ -std=c++11 -DGCC -m64 --shared -fPIC -o ../../../../MKL/Linux/x64/MathNet.Numerics.MKL.dll -I$MKL/include -I../Common ../MKL/vector_functions.c ../MKL/blas.c ../MKL/lapack.cpp -Wl,--start-group $MKL/lib/intel64/libmkl_intel_lp64.a $MKL/lib/intel64/libmkl_intel_thread.a $MKL/lib/intel64/libmkl_core.a -Wl,--end-group -L$OPENMP/intel64 -liomp5 -lpthread -lm +mkdir -p $OUT/x64 +mkdir -p $OUT/x86 -cp $OPENMP/intel64/libiomp5.so ../../../../MKL/Linux/x64/ +g++ -std=c++11 -DGCC -m64 --shared -fPIC -o $OUT/x64/MathNet.Numerics.MKL.dll -I$MKL/include -I../Common ../MKL/memory.c ../MKL/capabilities.cpp ../MKL/vector_functions.c ../MKL/blas.c ../MKL/lapack.cpp -Wl,--start-group $MKL/lib/intel64/libmkl_intel_lp64.a $MKL/lib/intel64/libmkl_intel_thread.a $MKL/lib/intel64/libmkl_core.a -Wl,--end-group -L$OPENMP/intel64 -liomp5 -lpthread -lm -g++ -std=c++11 -DGCC -m32 --shared -fPIC -o ../../../../MKL/Linux/x86/MathNet.Numerics.MKL.dll -I$MKL/include -I../Common ../MKL/vector_functions.c ../MKL/blas.c ../MKL/lapack.cpp -Wl,--start-group $MKL/lib/ia32/libmkl_intel.a $MKL/lib/ia32/libmkl_intel_thread.a $MKL/lib/ia32/libmkl_core.a -Wl,--end-group -L$OPENMP/ia32 -liomp5 -lpthread -lm +cp $OPENMP/intel64/libiomp5.so $OUT/x64/ -cp $OPENMP/ia32/libiomp5.so ../../../../MKL/Linux/x86/ +g++ -std=c++11 -DGCC -m32 --shared -fPIC -o $OUT/x86/MathNet.Numerics.MKL.dll -I$MKL/include -I../Common ../MKL/memory.c ../MKL/capabilities.cpp ../MKL/vector_functions.c ../MKL/blas.c ../MKL/lapack.cpp -Wl,--start-group $MKL/lib/ia32/libmkl_intel.a $MKL/lib/ia32/libmkl_intel_thread.a $MKL/lib/ia32/libmkl_core.a -Wl,--end-group -L$OPENMP/ia32 -liomp5 -lpthread -lm + +cp $OPENMP/ia32/libiomp5.so $OUT/x86/ diff --git a/src/NativeProviders/MKL/lapack.cpp b/src/NativeProviders/MKL/lapack.cpp index 1ad5a353..69b7e965 100644 --- a/src/NativeProviders/MKL/lapack.cpp +++ b/src/NativeProviders/MKL/lapack.cpp @@ -1,4 +1,4 @@ -#include +#include #include #define MKL_Complex8 std::complex #define MKL_Complex16 std::complex diff --git a/src/NativeProviders/MKL/memory.c b/src/NativeProviders/MKL/memory.c new file mode 100644 index 00000000..e5ec9f21 --- /dev/null +++ b/src/NativeProviders/MKL/memory.c @@ -0,0 +1,30 @@ +#include "wrapper_common.h" +#include "mkl.h" + +#if GCC +extern "C" { +#endif + +DLLEXPORT void free_buffers(void) { + mkl_free_buffers(); +} + +DLLEXPORT void thread_free_buffers(void) { + mkl_thread_free_buffers(); +} + +DLLEXPORT int disable_fast_mm(void) { + return mkl_disable_fast_mm(); +} + +DLLEXPORT MKL_INT64 mem_stat(int* AllocatedBuffers) { + return mkl_mem_stat(AllocatedBuffers); +} + +DLLEXPORT MKL_INT64 peak_mem_usage(int mode) { + return mkl_peak_mem_usage(mode); +} + +#if GCC +} +#endif \ No newline at end of file diff --git a/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj b/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj index c74c7519..26d4874d 100644 --- a/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj +++ b/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj @@ -293,6 +293,7 @@ + diff --git a/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj.filters b/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj.filters index d8da27eb..9ccf129e 100644 --- a/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj.filters +++ b/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj.filters @@ -30,6 +30,9 @@ Source Files + + Source Files + diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs index b445dc28..11e89256 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs @@ -67,6 +67,29 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl Double = 0x20 } + public enum MklMemoryRequestMode : int + { + /// + /// Disable gathering memory usage + /// + Disable = 0, + + /// + /// Enable gathering memory usage + /// + Enable = 1, + + /// + /// Return peak memory usage + /// + PeakMemory = 2, + + /// + /// Return peak memory usage and reset counter + /// + PeakMemoryReset = -1 + } + /// /// Intel's Math Kernel Library (MKL) linear algebra provider. /// @@ -163,10 +186,55 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl } } + /// + /// Frees the memory allocated to the MKL memory pool. + /// + public void FreeBuffers() + { + SafeNativeMethods.free_buffers(); + } + + /// + /// Frees the memory allocated to the MKL memory pool on the current thread. + /// + public void ThreadFreeBuffers() + { + SafeNativeMethods.thread_free_buffers(); + } + + /// + /// Disable the MKL memory pool. May impact performance. + /// + public void DisableMklMemoryPool() + { + SafeNativeMethods.disable_fast_mm(); + } + + /// + /// Retrieves information about the the MKL memory pool. + /// + /// On output, returns the number of memory buffers allocated. + /// Returns the number of bytes allocated to all memory buffers. + public long MemoryStatistics(out int allocatedBuffers) + { + return SafeNativeMethods.mem_stat(out allocatedBuffers); + } + + /// + /// Measures peak memory usage of the MKL memory pool. + /// + /// The request mode. + /// The peak memory usage. + public long PeakMemoryUsage(MklMemoryRequestMode mode) + { + return SafeNativeMethods.peak_mem_usage((int)mode); + } + public override string ToString() { return string.Format("Intel MKL ({1}; revision {0})", _nativeRevision, _nativeIX86 ? "x86" : _nativeX64 ? "x64" : _nativeIA64 ? "IA64" : "unknown"); } + } } diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs index 357c7c07..b0e148c9 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs @@ -2,7 +2,7 @@ // Math.NET Numerics, part of the Math.NET Project // http://mathnet.opensourcedotnet.info // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2014 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -60,6 +60,24 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] internal static extern void set_max_threads(int num_threads); + #region Memory + [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] + internal static extern void free_buffers(); + + [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] + internal static extern void thread_free_buffers(); + + [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] + internal static extern int disable_fast_mm(); + + [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] + internal static extern long mem_stat([Out]out int allocatedBuffers); + + [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] + internal static extern long peak_mem_usage(int mode); + + #endregion Memory + #region BLAS [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]