Browse Source

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

pull/203/head
Christoph Ruegg 12 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 "mkl.h"
#ifdef __cplusplus
extern "C" {
@ -40,7 +41,8 @@ extern "C" {
#endif
// COMMON/SHARED
case 64: return 4; // revision
case 64: return 5; // revision
case 65: return 1; // numerical consistency, precision and accuracy modes
// 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
}
#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);
}
}
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://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
// obtaining a copy of this software and associated documentation
@ -34,6 +34,39 @@ using System;
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>
/// Intel's Math Kernel Library (MKL) linear algebra provider.
/// </summary>
@ -44,17 +77,37 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
bool _nativeX64 = false;
bool _nativeIA64 = false;
/// <param name="bitConsistent">If true improves MKL Consistency to get bit consistent results on repeated identical calculations</param>
public MklLinearAlgebraProvider(bool bitConsistent = false)
readonly MklConsistency _consistency;
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)
{
SafeNativeMethods.SetImprovedConsistency();
}
_consistency = consistency;
_precision = precision;
_accuracy = accuracy;
}
public MklLinearAlgebraProvider()
{
_consistency = MklConsistency.Auto;
_precision = MklPrecision.Double;
_accuracy = MklAccuracy.High;
}
/// <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>
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).");
}
if (SafeNativeMethods.query_capability(65) > 0)
{
SafeNativeMethods.set_consistency_mode((int)_consistency);
SafeNativeMethods.set_vml_mode((uint)_precision | (uint)_accuracy);
}
}
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)]
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
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
@ -103,9 +109,6 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
#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)]
internal static extern float s_matrix_norm(byte norm, int rows, int columns, [In] float[] a, [In, Out] float[] work);

Loading…
Cancel
Save