为了练习,我正在用 cuda 编写一个简单的矩阵初始化程序。作为起点,我制作了一个小的顺序版本以供引用。它只是创建一个 n x m 数组并用 double 填充它。我一直在阅读其他帖子和文档,但我很困惑,我希望有人能向我解释如何在 cuda 中以类似于我在下面所做的 n x m 大小的方式初始化二维数组。如果有人愿意解释,我也很感激关于如何填充该 cuda 矩阵的见解。
您好,关于它是否可能重复,我应该详细说明。链接的帖子并没有真正解释任何东西,它只是示例代码,它是我之前查看过但不理解的帖子之一,因为它没有解释。谢谢。
顺序版本:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
int n,m, i, j;
double count;
void update(int n, int m, double arr[][m]){
for(i=0; i<n; i++){
for(j=0; j<m; j++){
count++;
arr[i][j] = count;
}
}
}
int main(int argc, char * argv[]) {
assert(argc==3);
n = atoi(argv[2]);
m = atoi(argv[1]);
double (*arr)[n][m] = malloc(sizeof *arr);
update(n,m,arr);
return 0;
}
最佳答案
您可以在一维中模拟二维数组,逐行保存数据。这样二维数组: [a,b][c,d] 变为 [a,b,c,d]。为了简单起见,您可以编写一个提供此类功能的包装类。
这是这个想法的演示(不是 100% 防灾,但有效)
#pragma once
#include <iostream>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
typedef int TYPE;
// NOTE: copy consturctor and = operator need to be overloaded as well
template<class T>
struct Matrix
{
Matrix(int r, int c) : rows(r), cols(c) {
data = new T[r*c];
}
~Matrix() {
// As we allocated memory it needs to be freed upon destruction
delete[] data;
data = nullptr;
}
int rows, cols;
T* data;
T* operator[](int row) {
// Returns pointer to "ROW", further call to [] on result will retrieve item at column in this row
return data + (row*cols);
}
};
// Simple cuda kernel
__global__ void add(TYPE *a, TYPE *b, TYPE *c, int rows, int cols) {
// Get element row and col
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
// If kernel block/grid is not sized perfectly make sure not to step outside data bounds
if(row < rows && col < cols)
{
int idx = row*cols + col;
c[idx] = a[idx] + b[idx];
}
}
int main() {
// m3 = m1 + m2 using cuda
int rows = 5, cols = 5, total = rows * cols;
Matrix<TYPE> m1{ rows,cols }, m2{ rows,cols }, m3{ rows,cols };
// Initialization as 1D array
for(int i = 0; i < total; i++) {
m1.data[i] = i;
}
// Or initialization as 2D array
for(int r = 0; r < rows; r++)
for(int c = 0; c < cols; c++)
m2[r][c] = r*cols + c + 100;
for(int i = 0; i < total; i++) std::cout << m1.data[i] << ", ";
std::cout << "\n";
for(int r = 0; r < rows; r++) {
for(int c = 0; c < cols; c++)
std::cout << m2[r][c] << ", ";
std::cout << "\n";
}
// CUDA part
TYPE *d_m1, *d_m2, *d_m3;
// Allocation
cudaMalloc((void **) &d_m1, total * sizeof(TYPE));
cudaMalloc((void **) &d_m2, total * sizeof(TYPE));
cudaMalloc((void **) &d_m3, total * sizeof(TYPE));
// Copy m1 and m2 to GPU
cudaMemcpy(d_m1, m1.data, total * sizeof(TYPE), cudaMemcpyHostToDevice);
cudaMemcpy(d_m2, m2.data, total * sizeof(TYPE), cudaMemcpyHostToDevice);
// Oversized on purpose to show row/col guard on add kernel
dim3 grid(5, 5);
dim3 block(5, 5);
add <<< grid, block >>> (d_m1, d_m2, d_m3, rows, cols);
// Copy result to m3
cudaMemcpy(m3.data, d_m3, total * sizeof(TYPE), cudaMemcpyDeviceToHost);
cudaFree(d_m1);
cudaFree(d_m2);
cudaFree(d_m3);
for(int r = 0; r < rows; r++) {
for(int c = 0; c < cols; c++)
std::cout << m3[r][c] << ", ";
std::cout << "\n";
}
system("pause");
return 0;
}
关于c - 你如何在cuda中创建一个二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53513095/