Добавил:
Upload
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:CUDA_full / P03_MatrixMultiplication / CUDA_MMult_completed / main
.cpp#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;
}