Mathnet и Unity - Проблема с производительности для разреженной матрицыC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Mathnet и Unity - Проблема с производительности для разреженной матрицы

Сообщение Anonymous »

Я использую библиотеку Mathnet в моем проекте Unity. Для этого я установил пакет NugetForunity, который позволяет мне установить практически любой пакет, доступный в Nuget в Unity. С этим мне удалось установить Mathnet V5 в моем проекте Unity, и он работает нормально. > Чтобы решить большую сложную разреженную матрицу (ax = b, размером около 10 тыс.*10 тыс. /> проблема
Использование прямого или итерационного решателя на редкой матрице не использует аппаратное ускорение.
попытка решения < /strong> < /p>
Установка библиотеки для предлагаемого нативного поставщика: < /p>
  • cuda и openblas : не удалось правильно установить их в Unity, чтобы библиотека Mathnet обнаружила их < /li>
    MKL: успешно установлен и обнаружение Mathnet. Использует ли ускорение аппаратного обеспечения для Densematrix, но не для разреженной матрицы.

Вопрос

Поддерживает ли Mathnet ускорение аппаратного обеспечения для решения сложной разреженной матрицы? Если да, с каким нативным поставщиком? /strong> < /p>
  • unity версия 6 < /p>
    < /li>
    Пакет Установлено:

    mathnet.numerics.mkl.win-x64.3.0.0 (2 DLL среды выполнения необходимо иметь нагрузку на флажке запуска, чтобы Mathnet их нашел) < /li>
    mathnet.numerics.providers.cuda.5.0.0
  • mathnet.numerics.providers.mkl.5.0.0.0
  • mathnet.numerics.providers.openblas.5.0.0
< /li>
Пример код Использование для тестирования производительности: < /p>
< /li>
< /ul>
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();
}
}


Подробнее здесь: https://stackoverflow.com/questions/794 ... rse-matrix
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»