Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
16
Добавлен:
27.03.2015
Размер:
2.47 Кб
Скачать
#include <cstdlib>
#include <iomanip>
#include <iostream>

#include <cublas.h>

#include "minres.h"

int main()
{
    // Размер системы.
    const int n = 1024;
    // Число итераций.
    const int iterations = 100;

    cublasInit();

    // Исходные данные.
    float * A, * b, * x;

    A = new float[n * n];
    b = new float[n];
    x = new float[n];

    // Заполним матрицу случайно, но чтобы она была положительно определена.
    for (int i = 0; i < n * n; ++i)
        A[i] = std::rand() / float(RAND_MAX);
    for (int i = 0; i < n; ++i)
        A[i * n + i] += float(n);


    // Заполним правую часть случайно.
    for (int i = 0; i < n; ++i)
        b[i] = std::rand() / float(RAND_MAX);

    // Заполним начальное приближение нулями.
    for (int i = 0; i < n; ++i)
        x[i] = 0;

    // Соответствующие массивы на GPU.
    float * A_gpu, * b_gpu, * x_gpu;

    cublasAlloc(n * n, sizeof(float), (void **) &A_gpu);
    cublasAlloc(n, sizeof(float), (void **) &b_gpu);
    cublasAlloc(n, sizeof(float), (void **) &x_gpu);

    // Копируем исходные данные.
    cublasSetVector(n * n, sizeof(float), A, 1, A_gpu, 1);
    cublasSetVector(n, sizeof(float), b, 1, b_gpu, 1);
    cublasSetVector(n, sizeof(float), x, 1, x_gpu, 1);

    // Вспомогательные массивы.
    float * r_gpu, * Ar_gpu;
    cublasAlloc(n, sizeof(float), (void **) &r_gpu);
    cublasAlloc(n, sizeof(float), (void **) &Ar_gpu);

    // Для удобства, забьём Ar нулями.
    cublasSetVector(n, sizeof(float), x, 1, Ar_gpu, 1);

    // Запускаем метод.
    for (int i = 0; i < iterations; ++i)
        min_residual_gpu(n, A_gpu, b_gpu, x_gpu, r_gpu, Ar_gpu);

    // Копируем результат обратно.
    cublasGetVector(n, sizeof(float), x_gpu, 1, x, 1);

    // Считаем норму Ax - b. Заметим, что в CUBLAS матрицы считаются хранящимися
    // по столбцам.
    float difference = 0;

    for (int i = 0; i < n; ++i)
    {
        float element = 0;
        for (int j = 0; j < n; ++j)
            element += A[j * n + i] * x[j];
        difference += (element - b[i]) * (element - b[i]);
    }

    std::cout << std::fixed << std::setprecision(4);
    std::cout << "||Ax - b||^2 = " << difference << "\n";

    cublasFree(Ar_gpu);
    cublasFree(r_gpu);
    cublasFree(x_gpu);
    cublasFree(b_gpu);
    cublasFree(A_gpu);

    delete [] x;
    delete [] b;
    delete [] A;

    cublasShutdown();
}
Соседние файлы в папке CUDA_MinResidual