Browse Source

Native Providers: first class support for freeing resources

spatial
Christoph Ruegg 9 years ago
parent
commit
85129ef243
  1. 23
      src/Numerics.Tests/Providers/FourierTransform/FourierTransformProviderTests.cs
  2. 19
      src/Numerics.Tests/Providers/LinearAlgebra/Double/LinearAlgebraProviderTests.cs
  3. 6
      src/Numerics/Control.cs
  4. 9
      src/Numerics/Providers/Common/Cuda/CudaProvider.cs
  5. 15
      src/Numerics/Providers/Common/Mkl/MklProvider.cs
  6. 9
      src/Numerics/Providers/Common/OpenBlas/OpenBlasProvider.cs
  7. 5
      src/Numerics/Providers/FourierTransform/FourierTransformControl.cs
  8. 6
      src/Numerics/Providers/FourierTransform/IFourierTransformProvider.cs
  9. 8
      src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs
  10. 9
      src/Numerics/Providers/FourierTransform/Mkl/MklFourierTransformProvider.cs
  11. 10
      src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs
  12. 8
      src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs
  13. 6
      src/Numerics/Providers/LinearAlgebra/LinearAlgebraControl.cs
  14. 8
      src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.cs
  15. 16
      src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs
  16. 16
      src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs

23
src/Numerics.Tests/Providers/FourierTransform/FourierTransformProviderTests.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// //
// Copyright (c) 2009-2016 Math.NET // Copyright (c) 2009-2018 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
@ -42,6 +42,27 @@ namespace MathNet.Numerics.UnitTests.Providers.FourierTransform
[TestFixture, Category("LAProvider")] [TestFixture, Category("LAProvider")]
public class FourierTransformProviderTests public class FourierTransformProviderTests
{ {
[Test]
public void ProviderSurvivesFreeResources()
{
var samples = Generate.PeriodicMap(16, w => new Complex(Math.Sin(w), 0), 16, 1.0, Constants.Pi2);
var spectrum1 = new Complex[samples.Length];
samples.Copy(spectrum1);
FourierTransformControl.Provider.Forward(spectrum1, FourierTransformScaling.ForwardScaling);
FourierTransformControl.FreeResources();
var spectrum2 = new Complex[samples.Length];
samples.Copy(spectrum2);
FourierTransformControl.Provider.Forward(spectrum2, FourierTransformScaling.ForwardScaling);
for (var i = 0; i < spectrum1.Length; i++)
{
Assert.AreEqual(spectrum1[i], spectrum2[i]);
}
}
[Test] [Test]
public void ForwardInplaceRealSine() public void ForwardInplaceRealSine()
{ {

19
src/Numerics.Tests/Providers/LinearAlgebra/Double/LinearAlgebraProviderTests.cs

@ -72,6 +72,25 @@ namespace MathNet.Numerics.UnitTests.Providers.LinearAlgebra.Double
{ "Square1000x1000", (DenseMatrix)Matrix<double>.Build.Random(1000, 1000, Dist) } { "Square1000x1000", (DenseMatrix)Matrix<double>.Build.Random(1000, 1000, Dist) }
}; };
[Test]
public void ProviderSurvivesFreeResources()
{
var samples = Generate.PeriodicMap(16, w => Math.Sin(w), 16, 1.0, Constants.Pi2);
var result1 = new double[samples.Length];
LinearAlgebraControl.Provider.ScaleArray(2.5, samples, result1);
LinearAlgebraControl.FreeResources();
var result2 = new double[samples.Length];
LinearAlgebraControl.Provider.ScaleArray(2.5, samples, result2);
for (var i = 0; i < result1.Length; i++)
{
Assert.AreEqual(result1[i], result2[i]);
}
}
/// <summary> /// <summary>
/// Can add a vector to scaled vector /// Can add a vector to scaled vector
/// </summary> /// </summary>

6
src/Numerics/Control.cs

@ -190,6 +190,12 @@ namespace MathNet.Numerics
} }
#endif #endif
public static void FreeResources()
{
LinearAlgebraControl.FreeResources();
FourierTransformControl.FreeResources();
}
public static void UseSingleThread() public static void UseSingleThread()
{ {
_maxDegreeOfParallelism = 1; _maxDegreeOfParallelism = 1;

9
src/Numerics/Providers/Common/Cuda/CudaProvider.cs

@ -113,6 +113,15 @@ namespace MathNet.Numerics.Providers.Common.Cuda
return _nativeRevision; return _nativeRevision;
} }
/// <summary>
/// Frees memory buffers, caches and handles allocated in or to the provider.
/// Does not unload the provider itself, it is still usable afterwards.
/// This method is safe to call, even if the provider is not loaded.
/// </summary>
public static void FreeResources()
{
}
public static string Describe() public static string Describe()
{ {
if (!_loaded) if (!_loaded)

15
src/Numerics/Providers/Common/Mkl/MklProvider.cs

@ -154,6 +154,21 @@ namespace MathNet.Numerics.Providers.Common.Mkl
} }
} }
/// <summary>
/// Frees memory buffers, caches and handles allocated in or to the provider.
/// Does not unload the provider itself, it is still usable afterwards.
/// This method is safe to call, even if the provider is not loaded.
/// </summary>
public static void FreeResources()
{
if (!_loaded)
{
return;
}
FreeBuffers();
}
/// <summary> /// <summary>
/// Frees the memory allocated to the MKL memory pool. /// Frees the memory allocated to the MKL memory pool.
/// </summary> /// </summary>

9
src/Numerics/Providers/Common/OpenBlas/OpenBlasProvider.cs

@ -121,6 +121,15 @@ namespace MathNet.Numerics.Providers.Common.OpenBlas
return _nativeRevision; return _nativeRevision;
} }
/// <summary>
/// Frees memory buffers, caches and handles allocated in or to the provider.
/// Does not unload the provider itself, it is still usable afterwards.
/// This method is safe to call, even if the provider is not loaded.
/// </summary>
public static void FreeResources()
{
}
internal static void ConfigureThreading() internal static void ConfigureThreading()
{ {
if (!_loaded) if (!_loaded)

5
src/Numerics/Providers/FourierTransform/FourierTransformControl.cs

@ -170,6 +170,11 @@ namespace MathNet.Numerics.Providers.FourierTransform
#endif #endif
} }
public static void FreeResources()
{
Provider.FreeResources();
}
static string GetCombinedHintPath() static string GetCombinedHintPath()
{ {
if (!String.IsNullOrEmpty(HintPath)) if (!String.IsNullOrEmpty(HintPath))

6
src/Numerics/Providers/FourierTransform/IFourierTransformProvider.cs

@ -52,6 +52,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// </summary> /// </summary>
void InitializeVerify(); void InitializeVerify();
/// <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>
void FreeResources();
void Forward(Complex32[] samples, FourierTransformScaling scaling); void Forward(Complex32[] samples, FourierTransformScaling scaling);
void Forward(Complex[] samples, FourierTransformScaling scaling); void Forward(Complex[] samples, FourierTransformScaling scaling);
void Backward(Complex32[] spectrum, FourierTransformScaling scaling); void Backward(Complex32[] spectrum, FourierTransformScaling scaling);

8
src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs

@ -50,6 +50,14 @@ namespace MathNet.Numerics.Providers.FourierTransform
{ {
} }
/// <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 virtual void FreeResources()
{
}
public override string ToString() public override string ToString()
{ {
return "Managed"; return "Managed";

9
src/Numerics/Providers/FourierTransform/Mkl/MklFourierTransformProvider.cs

@ -87,9 +87,10 @@ namespace MathNet.Numerics.Providers.FourierTransform.Mkl
} }
/// <summary> /// <summary>
/// Frees the memory allocated to the MKL memory pool. /// Frees memory buffers, caches and handles allocated in or to the provider.
/// Does not unload the provider itself, it is still usable afterwards.
/// </summary> /// </summary>
internal void FreeBuffers() public virtual void FreeResources()
{ {
Kernel kernel = Interlocked.Exchange(ref _kernel, null); Kernel kernel = Interlocked.Exchange(ref _kernel, null);
if (kernel != null) if (kernel != null)
@ -97,7 +98,7 @@ namespace MathNet.Numerics.Providers.FourierTransform.Mkl
SafeNativeMethods.x_fft_free(ref kernel.Handle); SafeNativeMethods.x_fft_free(ref kernel.Handle);
} }
MklProvider.FreeBuffers(); MklProvider.FreeResources();
} }
public override string ToString() public override string ToString()
@ -362,7 +363,7 @@ namespace MathNet.Numerics.Providers.FourierTransform.Mkl
public void Dispose() public void Dispose()
{ {
FreeBuffers(); FreeResources();
} }
} }
} }

10
src/Numerics/Providers/LinearAlgebra/Cuda/CudaLinearAlgebraProvider.cs

@ -84,6 +84,15 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda
Solver(SafeNativeMethods.createSolverHandle(ref _solverHandle)); Solver(SafeNativeMethods.createSolverHandle(ref _solverHandle));
} }
/// <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()
{
CudaProvider.FreeResources();
}
private void BLAS(int status) private void BLAS(int status)
{ {
switch (status) switch (status)
@ -177,6 +186,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Cuda
{ {
BLAS(SafeNativeMethods.destroyBLASHandle(_blasHandle)); BLAS(SafeNativeMethods.destroyBLASHandle(_blasHandle));
Solver(SafeNativeMethods.destroySolverHandle(_solverHandle)); Solver(SafeNativeMethods.destroySolverHandle(_solverHandle));
FreeResources();
} }
} }
} }

8
src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// //
// Copyright (c) 2009-2013 Math.NET // Copyright (c) 2009-2018 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
@ -99,6 +99,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// Initialize and verify that the provided is indeed available. If not, fall back to alternatives like the managed provider /// Initialize and verify that the provided is indeed available. If not, fall back to alternatives like the managed provider
/// </summary> /// </summary>
void InitializeVerify(); void InitializeVerify();
/// <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>
void FreeResources();
} }
/// <summary> /// <summary>

6
src/Numerics/Providers/LinearAlgebra/LinearAlgebraControl.cs

@ -28,6 +28,7 @@
// </copyright> // </copyright>
using System; using System;
using System.Net;
namespace MathNet.Numerics.Providers.LinearAlgebra namespace MathNet.Numerics.Providers.LinearAlgebra
{ {
@ -220,6 +221,11 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
#endif #endif
} }
public static void FreeResources()
{
Provider.FreeResources();
}
static string GetCombinedHintPath() static string GetCombinedHintPath()
{ {
if (!String.IsNullOrEmpty(HintPath)) if (!String.IsNullOrEmpty(HintPath))

8
src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.cs

@ -70,6 +70,14 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
{ {
} }
/// <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 virtual void FreeResources()
{
}
public override string ToString() public override string ToString()
{ {
return "Managed"; return "Managed";

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

@ -48,7 +48,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
/// <summary> /// <summary>
/// Intel's Math Kernel Library (MKL) linear algebra provider. /// Intel's Math Kernel Library (MKL) linear algebra provider.
/// </summary> /// </summary>
internal partial class MklLinearAlgebraProvider : ManagedLinearAlgebraProvider internal partial class MklLinearAlgebraProvider : ManagedLinearAlgebraProvider, IDisposable
{ {
const int _minimumCompatibleRevision = 4; const int _minimumCompatibleRevision = 4;
@ -112,10 +112,24 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
} }
} }
/// <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() public override string ToString()
{ {
return MklProvider.Describe(); return MklProvider.Describe();
} }
public void Dispose()
{
FreeResources();
}
} }
} }

16
src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs

@ -55,7 +55,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas
/// <summary> /// <summary>
/// OpenBLAS linear algebra provider. /// OpenBLAS linear algebra provider.
/// </summary> /// </summary>
internal partial class OpenBlasLinearAlgebraProvider : ManagedLinearAlgebraProvider internal partial class OpenBlasLinearAlgebraProvider : ManagedLinearAlgebraProvider, IDisposable
{ {
const int _minimumCompatibleRevision = 1; const int _minimumCompatibleRevision = 1;
@ -97,10 +97,24 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas
} }
} }
/// <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()
{
OpenBlasProvider.FreeResources();
}
public override string ToString() public override string ToString()
{ {
return OpenBlasProvider.Describe(); return OpenBlasProvider.Describe();
} }
public void Dispose()
{
FreeResources();
}
} }
} }

Loading…
Cancel
Save