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

#include <cuda_runtime_api.h>

#include "mmult.h"


// Проверка результата, c_gpu - указатель на память GPU.
void check(const float * c, const float * c_gpu, int m, int k)
{
    float * c_verify = new float[m * k];
    cudaMemcpy(c_verify, c_gpu, m * k * sizeof *c_gpu,
        cudaMemcpyDeviceToHost);

    float difference = 0;
    for (int i = 0; i < m * k; ++i)
        difference += (c[i] - c_verify[i]) * (c[i] - c_verify[i]);
    if (difference < 1e-5f)
        std::cout << "Test PASSED.";
    else
        std::cout << "Test FAILED (diff = " << difference << ").";
    std::cout << "\n";

    delete [] c_verify;
}


// Запуск всех 3х версий для заданных m, n, k
void runTest(int m, int n, int k)
{
    // a — матрица m x n
    float * a = new float[m * n];
    float * a_gpu;
    cudaMalloc((void **) &a_gpu, m * n * sizeof(float));

    // b — матрица n x k
    float * b = new float[n * k];
    float * b_gpu;
    cudaMalloc((void **) &b_gpu, n * k * sizeof(float));

    // c — матрица m x k
    float * c = new float[m * k];
    float * c_gpu_1, * c_gpu_2, * c_gpu_3;
    cudaMalloc((void **) &c_gpu_1, m * k * sizeof(float));
    cudaMalloc((void **) &c_gpu_2, m * k * sizeof(float));
    cudaMalloc((void **) &c_gpu_3, m * k * sizeof(float));

    // Заполним матрицы случайнымм образом.
    for (int i = 0; i < m * n; ++i)
        a[i] = float(rand()) / RAND_MAX;
    for (int i = 0; i < n * k; ++i)
        b[i] = float(rand()) / RAND_MAX;

    // Скопируем входные данные на GPU.
    cudaMemcpy(a_gpu, a, m * n * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(b_gpu, b, n * k * sizeof(float), cudaMemcpyHostToDevice);

    // Запуск CPU-версии
    mmult(m, n, k, a, b, c);

    // Запуск и проверка GPU-версий
    std::cout << "Version 1: ";
    mmult_gpu_1(m, n, k, a_gpu, b_gpu, c_gpu_1);
    check(c, c_gpu_1, m, k);

    std::cout << "Version 2: ";
    mmult_gpu_2(m, n, k, a_gpu, b_gpu, c_gpu_2);
    check(c, c_gpu_2, m, k);

    std::cout << "Version 3: ";
    mmult_gpu_3(m, n, k, a_gpu, b_gpu, c_gpu_3);
    check(c, c_gpu_3, m, k);

    // Освободим память.
    cudaFree(c_gpu_1);
    cudaFree(c_gpu_2);
    cudaFree(c_gpu_3);
    delete [] c;
    cudaFree(b_gpu);
    delete [] b;
    cudaFree(a_gpu);
    delete [] a;
}



int main()
{
    int m, n, k;

    // Запустим тест 2 раза:
    // 1) когда m, n, k кратны BLOCK_SIZE
    std::cout << "Test 1: m = 2 * BLOCK_SIZE, n = 3 * BLOCK_SIZE, k = 5 * BLOCK_SIZE\n";
    m = 2 * BLOCK_SIZE;
    n = 3 * BLOCK_SIZE;
    k = 5 * BLOCK_SIZE;
    runTest(m, n, k);
    std::cout << "\n\n";

    // 2) когда m, n, k не кратны BLOCK_SIZE
    std::cout << "Test 1: m = 2 * BLOCK_SIZE + 4, n = 3 * BLOCK_SIZE + 1, k = 5 * BLOCK_SIZE + 7\n";
    m = 2 * BLOCK_SIZE + 4;
    n = 3 * BLOCK_SIZE + 1;
    k = 5 * BLOCK_SIZE + 7;
    runTest(m, n, k);

    return 0;
}
Соседние файлы в папке CUDA_MMult