ningshuxia
2022-12-12 e78f5936fee9ab4fff600515bb20a41a28f329c4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#if NATIVE
 
using IStation.Numerics.Providers.Common.Mkl;
using System;
 
namespace IStation.Numerics.Providers.SparseSolver.Mkl
{
    /// <summary>
    /// Intel's Math Kernel Library (MKL) sparse solver provider.
    /// </summary>
    internal partial class MklSparseSolverProvider : Managed.ManagedSparseSolverProvider, IDisposable
    {
        const int MinimumCompatibleRevision = 14;
 
        readonly string _hintPath;
 
        int sparseSolverMajor;
        int sparseSolverMinor;
 
        /// <param name="hintPath">Hint path where to look for the native binaries</param>
        internal MklSparseSolverProvider(string hintPath)
        {
            _hintPath = hintPath;
        }
 
        /// <summary>
        /// Try to find out whether the provider is available, at least in principle.
        /// Verification may still fail if available, but it will certainly fail if unavailable.
        /// </summary>
        public override bool IsAvailable()
        {
            return MklProvider.IsAvailable(hintPath: _hintPath);
        }
 
        /// <summary>
        /// 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()
        {
            int revision = MklProvider.Load(_hintPath);
            if (revision < MinimumCompatibleRevision)
            {
                throw new NotSupportedException($"MKL Native Provider revision r{revision} is too old. Consider upgrading to a newer version. Revision r{MinimumCompatibleRevision} and newer are supported.");
            }
 
            sparseSolverMajor = SafeNativeMethods.query_capability((int)ProviderCapability.SparseSolverMajor);
            sparseSolverMinor = SafeNativeMethods.query_capability((int)ProviderCapability.SparseSolverMinor);
            if (!(sparseSolverMajor == 1 && sparseSolverMinor >= 0))
            {
                throw new NotSupportedException(string.Format("MKL Native Provider not compatible. Expecting sparse solver v1 but provider implements v{0}.", sparseSolverMajor));
            }
        }
 
        /// <summary>
        /// Frees memory buffers, caches and handles allocated in or to the provider.
        /// Does not unload the provider itself, it is still usable afterwards.
        /// </summary>
        public override void FreeResources()
        {
            MklProvider.FreeResources();
        }
 
        public override string ToString()
        {
            return MklProvider.Describe();
        }
 
        public void Dispose()
        {
            FreeResources();
        }
    }
}
 
#endif