帮我用cuda语言写一个矩阵乘案例
时间: 2023-09-04 18:03:59 浏览: 180
### 回答1:
好的,我可以回答这个问题。以下是一个使用 CUDA 语言编写的矩阵乘法示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
#define N 1024
__global__ void matrixMul(float *a, float *b, float *c, int n) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
if (i < n && j < n) {
float sum = ;
for (int k = ; k < n; k++) {
sum += a[i * n + k] * b[k * n + j];
}
c[i * n + j] = sum;
}
}
int main() {
float *a, *b, *c;
float *d_a, *d_b, *d_c;
int size = N * N * sizeof(float);
// Allocate memory on host
a = (float*)malloc(size);
b = (float*)malloc(size);
c = (float*)malloc(size);
// Initialize matrices
for (int i = ; i < N; i++) {
for (int j = ; j < N; j++) {
a[i * N + j] = i + j;
b[i * N + j] = i - j;
}
}
// Allocate memory on device
cudaMalloc((void**)&d_a, size);
cudaMalloc((void**)&d_b, size);
cudaMalloc((void**)&d_c, size);
// Copy matrices from host to device
cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, b, size, cudaMemcpyHostToDevice);
// Launch kernel
dim3 threadsPerBlock(16, 16);
dim3 numBlocks((N + threadsPerBlock.x - 1) / threadsPerBlock.x, (N + threadsPerBlock.y - 1) / threadsPerBlock.y);
matrixMul<<<numBlocks, threadsPerBlock>>>(d_a, d_b, d_c, N);
// Copy result from device to host
cudaMemcpy(c, d_c, size, cudaMemcpyDeviceToHost);
// Verify result
for (int i = ; i < N; i++) {
for (int j = ; j < N; j++) {
float sum = ;
for (int k = ; k < N; k++) {
sum += a[i * N + k] * b[k * N + j];
}
if (c[i * N + j] != sum) {
printf("Error: c[%d][%d] = %f, expected %f\n", i, j, c[i * N + j], sum);
return 1;
}
}
}
printf("Success!\n");
// Free memory
free(a);
free(b);
free(c);
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
return ;
}
```
这个程序使用 CUDA 在 GPU 上计算两个矩阵的乘积。程序首先在主机上分配内存,然后初始化矩阵。接着,程序在设备上分配内存,并将矩阵从主机复制到设备。然后,程序启动一个 CUDA 核函数,在 GPU 上计算矩阵乘积。最后,程序将结果从设备复制回主机,并验证结果是否正确。
### 回答2:
下面是一个使用CUDA语言编写的矩阵乘的案例代码,并附有相应的注释说明:
```c
#include <cuda_runtime.h>
#include <stdio.h>
#define N 4 // 矩阵的维度
// 定义矩阵乘的CUDA核函数
__global__ void matrixMul(int *a, int *b, int *c, int n) {
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
if (row < n && col < n) {
int temp = 0;
for (int k = 0; k < n; ++k) {
temp += a[row * n + k] * b[k * n + col];
}
c[row * n + col] = temp;
}
}
int main() {
// 定义并初始化输入矩阵a和b
int a[N][N] = {{1, 1, 1, 1}, {2, 2, 2, 2}, {3, 3, 3, 3}, {4, 4, 4, 4}};
int b[N][N] = {{1, 1, 1, 1}, {2, 2, 2, 2}, {3, 3, 3, 3}, {4, 4, 4, 4}};
// 计算矩阵大小以字节为单位
size_t bytes = N * N * sizeof(int);
// 在主机上分配内存并将矩阵a和b复制到设备上
int *d_a, *d_b, *d_c;
cudaMalloc((int **)&d_a, bytes);
cudaMalloc((int **)&d_b, bytes);
cudaMalloc((int **)&d_c, bytes);
cudaMemcpy(d_a, a, bytes, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, b, bytes, cudaMemcpyHostToDevice);
// 定义线程块和网格的大小
dim3 threadBlock(2, 2);
dim3 grid((N + threadBlock.x - 1) / threadBlock.x, (N + threadBlock.y - 1) / threadBlock.y);
// 调用CUDA核函数进行矩阵乘运算
matrixMul<<<grid, threadBlock>>>(d_a, d_b, d_c, N);
// 将结果矩阵c从设备上复制到主机上
int c[N][N];
cudaMemcpy(c, d_c, bytes, cudaMemcpyDeviceToHost);
// 打印结果矩阵c
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
printf("%d ", c[i][j]);
}
printf("\n");
}
// 释放设备上的内存
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
return 0;
}
```
以上代码实现了一个简单的矩阵乘运算,并利用CUDA并行计算的能力加快了计算速度。具体流程包括在主机上分配内存,将矩阵a和b复制到设备上,在设备上调用CUDA核函数进行计算,并将结果复制回主机进行打印。
### 回答3:
使用CUDA语言编写矩阵乘法的案例可以提高程序的并行性和性能。以下是一个示例:
```cuda
#include <stdio.h>
#include <stdlib.h>
#define N 1024 // 矩阵维度
// CUDA 核函数,用于计算矩阵乘法
__global__ void matrixMul(int *a, int *b, int *c)
{
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
int sum = 0;
for (int i = 0; i < N; ++i) {
sum += a[row * N + i] * b[i * N + col];
}
c[row * N + col] = sum;
}
int main()
{
int *a, *b, *c; // 输入和输出矩阵
int *dev_a, *dev_b, *dev_c; // GPU上的设备指针
int size = N * N * sizeof(int);
// 为输入和输出矩阵分配内存
a = (int*)malloc(size);
b = (int*)malloc(size);
c = (int*)malloc(size);
// 为GPU上的设备指针分配内存
cudaMalloc((void**)&dev_a, size);
cudaMalloc((void**)&dev_b, size);
cudaMalloc((void**)&dev_c, size);
// 初始化输入矩阵 a 和 b
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
a[i * N + j] = i;
b[i * N + j] = j;
}
}
// 将输入矩阵 a 和 b 从主机内存复制到GPU上的设备内存
cudaMemcpy(dev_a, a, size, cudaMemcpyHostToDevice);
cudaMemcpy(dev_b, b, size, cudaMemcpyHostToDevice);
// 设置grid和block的大小
dim3 grid(N/16, N/16, 1);
dim3 block(16, 16, 1);
// 调用GPU上的核函数进行矩阵乘法计算
matrixMul<<<grid, block>>>(dev_a, dev_b, dev_c);
// 将计算结果从GPU上的设备内存复制到主机内存
cudaMemcpy(c, dev_c, size, cudaMemcpyDeviceToHost);
// 打印输出矩阵 c
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
printf("%d ", c[i * N + j]);
}
printf("\n");
}
// 释放主机和设备内存
free(a);
free(b);
free(c);
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
return 0;
}
```
这个例子中,首先在主机上分配输入和输出矩阵的内存,并且在GPU上分配设备指针的内存。然后,使用`cudaMemcpy`将输入矩阵从主机内存复制到设备内存。接下来,设置grid和block的大小。在核函数`matrixMul`中,使用每个线程的唯一的索引计算矩阵的乘积。最后,再次使用`cudaMemcpy`将计算结果从设备内存复制到主机内存,并打印输出矩阵c。最后,释放内存。
阅读全文