Browse Source

MKL: consistency, precision and accuracy configurable, applied in Init #198

pull/203/head
Christoph Ruegg 13 years ago
parent
commit
b9b35fb191
  1. 22
      src/NativeProviders/MKL/capabilities.cpp
  2. 9
      src/NativeProviders/MKL/lapack.cpp
  3. 75
      src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs
  4. 9
      src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs

22
src/NativeProviders/MKL/capabilities.cpp

@ -1,4 +1,5 @@
#include "wrapper_common.h" #include "wrapper_common.h"
#include "mkl.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -40,7 +41,8 @@ extern "C" {
#endif #endif
// COMMON/SHARED // COMMON/SHARED
case 64: return 4; // revision case 64: return 5; // revision
case 65: return 1; // numerical consistency, precision and accuracy modes
// LINEAR ALGEBRA // LINEAR ALGEBRA
case 128: return 1; // basic dense linear algebra case 128: return 1; // basic dense linear algebra
@ -56,6 +58,24 @@ extern "C" {
} }
} }
DLLEXPORT void set_consistency_mode(const MKL_INT mode)
{
mkl_cbwr_set(mode);
}
DLLEXPORT void set_vml_mode(const MKL_UINT mode)
{
vmlSetMode(mode);
}
/* Obsolete, will be dropped in the next revision */
DLLEXPORT void SetImprovedConsistency(void)
{
// set improved consistency for MKL and vector functions
mkl_cbwr_set(MKL_CBWR_COMPATIBLE);
vmlSetMode(VML_HA | VML_DOUBLE_CONSISTENT);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

9
src/NativeProviders/MKL/lapack.cpp

@ -750,11 +750,4 @@ extern "C" {
return eigen_complex_factor<MKL_Complex16>(n, a, vectors, values, d, LAPACKE_zgees, LAPACKE_ztrevc); return eigen_complex_factor<MKL_Complex16>(n, a, vectors, values, d, LAPACKE_zgees, LAPACKE_ztrevc);
} }
} }
}
DLLEXPORT void SetImprovedConsistency(void)
{
// set improved consistency for mkl and vector functions
mkl_cbwr_set(MKL_CBWR_COMPATIBLE);
vmlSetMode(VML_HA|VML_DOUBLE_CONSISTENT);
}
}

75
src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2013 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -34,6 +34,39 @@ using System;
namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
{ {
/// <summary>
/// Consistency vs. performance trade-off between runs on different machines.
/// </summary>
public enum MklConsistency : int
{
/// <summary>Consistent on the same CPU only (maximum performance)</summary>
Auto = 2,
/// <summary>Consistent on Intel and compatible CPUs with SSE2 support (maximum compatibility)</summary>
Compatible = 3,
/// <summary>Consistent on Intel CPUs supporting SSE2 or later</summary>
SSE2 = 4,
/// <summary>Consistent on Intel CPUs supporting SSE4.2 or later</summary>
SSE4_2 = 8,
/// <summary>Consistent on Intel CPUs supporting AVX or later</summary>
AVX = 9,
/// <summary>Consistent on Intel CPUs supporting AVX2 or later</summary>
AVX2 = 10
}
[CLSCompliant(false)]
public enum MklAccuracy : uint
{
Low = 0x1,
High = 0x2
}
[CLSCompliant(false)]
public enum MklPrecision : uint
{
Single = 0x10,
Double = 0x20
}
/// <summary> /// <summary>
/// Intel's Math Kernel Library (MKL) linear algebra provider. /// Intel's Math Kernel Library (MKL) linear algebra provider.
/// </summary> /// </summary>
@ -44,17 +77,37 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
bool _nativeX64 = false; bool _nativeX64 = false;
bool _nativeIA64 = false; bool _nativeIA64 = false;
/// <param name="bitConsistent">If true improves MKL Consistency to get bit consistent results on repeated identical calculations</param> readonly MklConsistency _consistency;
public MklLinearAlgebraProvider(bool bitConsistent = false) readonly MklPrecision _precision;
readonly MklAccuracy _accuracy;
/// <param name="consistency">
/// Sets the desired bit consistency on repeated identical computations on varying CPU architectures,
/// as a trade-off with performance.
/// </param>
/// <param name="precision">VML optimal precision and rounding.</param>
/// <param name="accuracy">VML accuracy mode.</param>
[CLSCompliant(false)]
public MklLinearAlgebraProvider(
MklConsistency consistency = MklConsistency.Auto,
MklPrecision precision = MklPrecision.Double,
MklAccuracy accuracy = MklAccuracy.High)
{ {
if (bitConsistent) _consistency = consistency;
{ _precision = precision;
SafeNativeMethods.SetImprovedConsistency(); _accuracy = accuracy;
} }
public MklLinearAlgebraProvider()
{
_consistency = MklConsistency.Auto;
_precision = MklPrecision.Double;
_accuracy = MklAccuracy.High;
} }
/// <summary> /// <summary>
/// Initialize and verify that the provided is indeed available. If not, fall back to alernatives like the managed provider /// Initialize and verify that the provided is indeed available.
/// If calling this method fails, consider to fall back to alternatives like the managed provider.
/// </summary> /// </summary>
public override void InitializeVerify() public override void InitializeVerify()
{ {
@ -91,6 +144,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
{ {
throw new NotSupportedException("MKL Native Provider too old or not compatible (2)."); throw new NotSupportedException("MKL Native Provider too old or not compatible (2).");
} }
if (SafeNativeMethods.query_capability(65) > 0)
{
SafeNativeMethods.set_consistency_mode((int)_consistency);
SafeNativeMethods.set_vml_mode((uint)_precision | (uint)_accuracy);
}
} }
public override string ToString() public override string ToString()

9
src/Numerics/Providers/LinearAlgebra/Mkl/SafeNativeMethods.cs

@ -49,6 +49,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int query_capability(int capability); internal static extern int query_capability(int capability);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void set_consistency_mode(int mode);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void set_vml_mode(uint mode);
#region BLAS #region BLAS
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
@ -103,9 +109,6 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
#region LAPACK #region LAPACK
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void SetImprovedConsistency();
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern float s_matrix_norm(byte norm, int rows, int columns, [In] float[] a, [In, Out] float[] work); internal static extern float s_matrix_norm(byte norm, int rows, int columns, [In] float[] a, [In, Out] float[] work);

Loading…
Cancel
Save