Verwenden von direktem oder iterativem Solver auf einer spärlichen Matrix nutzt die Hardware -Beschleunigung nicht.
Versuchslösung < /strong> < /p>
Installation der Bibliothek für den vorgeschlagenen nativen Anbieter: < /p>
- CUDA und OpenBLAs : Es ist nicht gelungen, sie in Einheit ordnungsgemäß zu installieren, damit die MathNet -Bibliothek sie erfasst < /li>
MKL: erfolgreich installiert und von MathNet erfasst. Nutzt die Beschleunigung der Hardware für Densematrix, aber nicht für spärliche Matrix. Unterstützt MathNet die Beschleunigung der Hardware, um eine komplexe spärliche Matrix zu lösen? Wenn ja, mit welchem nativem Anbieter? /strong> < /p>
Einheit Version 6 < /p>
< /li>
Paket Installiert : < /p>
Mathnet.numerics Finden Sie sie) - Mathnet.numerics.providers.cuda.5.0.0
- Mathnet.numerics.providers.mkl.5.0.0
- Mathnet.numerics.providers.openblas.5.0.0
Beispielcode für den Leistungstest: < /p>
< /li>
< /ul>
Code: Select all
using UnityEngine;
using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics;
using System.Diagnostics;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.Statistics;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers;
using System.Threading;
using Debug = UnityEngine.Debug;
using Complex = System.Numerics.Complex;
public class PerformanceTest : MonoBehaviour
{
private Thread _t;
void Start()
{
//Reduce load of the unity renderer.
Application.targetFrameRate = 30;
//Configure the MathNet control
Control.ConfigureAuto();
Debug.Log($"Native MKL : {Control.TryUseNativeMKL()}");
Debug.Log(Control.Describe());
//We do the computation in a separate Thread otherwise Unity hang if it take too long.
Debug.Log("Starting Perf Task.");
_t = new Thread( () => {
Thread.CurrentThread.IsBackground = false;
PerfTest();
});
_t.Start();
}
private void PerfTest()
{
//Configure stopwatch for precise measurement
Stopwatch sw = new Stopwatch();
//Generate a N*N Matrix M and a dense vector b to solve Mx=b
sw.Start();
int N = 100000;
//DenseMatrix M = new DenseMatrix(N, N);
SparseMatrix M = new SparseMatrix(N, N);
DenseVector b = new DenseVector(N);
for (int k = 0; k < N; k++)
{
//Generate an arbitrary banded matrix for the example purpose
M[k, k] = new Complex(k / N, -k / N);
b[k] = new Complex(2 * k / N, -2 * k / N);
if (k > 0) M[k, k - 1] = new Complex(-5f, 0f);
if (k < N - 1) M[k, k + 1] = new Complex(-5f, 0f);
}
Debug.Log($"Generated a {N}*{N} Matrix in {TickToMS(sw.ElapsedTicks)} ms");
sw.Stop();
//Try To use LU factorisation to solve it and check result
sw.Restart();
var x = M.LU().Solve(b);
Debug.Log($"Solved using LU Factorisation in {TickToMS(sw.ElapsedTicks)} ms");
var err = M * x - b;
err.MapInplace(c => c.Magnitude, Zeros.AllowSkip);
double err_max = err.Enumerate().MaximumMagnitudePhase().Real;
Debug.Log($"Maximum error : {err_max}");
//Try to use an Iterative Solver
sw.Restart();
var iterationCountStopCriterion = new IterationCountStopCriterion(1000);
var residualStopCriterion = new ResidualStopCriterion(1e-10);
var monitor = new Iterator(iterationCountStopCriterion, residualStopCriterion);
var solver = new BiCgStab(); // The type of iterative solver can be changer here
x = M.SolveIterative(b, solver, monitor);
Debug.Log($"Solved using Iterative solver in {TickToMS(sw.ElapsedTicks)} ms");
err = M * x - b;
err.MapInplace(c => c.Magnitude, Zeros.AllowSkip);
err_max = err.Enumerate().MaximumMagnitudePhase().Real;
Debug.Log($"Maximum error : {err_max}.");
}
private float TickToMS(long tick)
{
return (1000f * tick)/(float)Stopwatch.Frequency;
}
private void OnDisable()
{
if (_t != null && _t.IsAlive)
_t.Abort();
}
}