使用指向结构的指针在设备内存中设置一个数组;在库达
Setting an array in device memory with a pointer to struct; in cuda
我正在尝试使用指向我在内核中创建的结构的指针来初始化内存中的数组。这是我到目前为止的代码,我不知道我做错了什么。如果我尝试对数组中的每个项目执行 cudaMalloc,则会出现分段错误,如果我不这样做,则会出现 "unspecified launch failure" 错误。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int status;
int location;
double distance;
} Point;
//Macro for checking cuda errors following a cuda launch or api call
#define cudaCheckError() {\
cudaError_t e=cudaGetLastError();\
if(e!=cudaSuccess) {\
printf("\nCuda failure %s:%d: '%s'\n",__FILE__,__LINE__,cudaGetErrorString(e));\
exit(0); \
}\
}
__global__ void kernel1(Point** d_memory, int limit){
int idx = blockIdx.x * blockDim.x * blockDim.y * blockDim.z
+ threadIdx.z * blockDim.y * blockDim.x
+ threadIdx.y * blockDim.x + threadIdx.x;
if(idx < limit) {
Point* pt = ( Point *) malloc( sizeof(Point) );
pt->distance = 10;
pt->location = -1;
pt->status = -1;
d_memory[idx] = pt;
}
}
__global__ void kernel2(Point** d_memory, int limit){
int i;
for (i=0; i<limit;i++){
printf("%f \n",d_memory[i]->distance);
}
}
int main(int argc, char *argv[])
{
int totalGrid = 257*193*129;
size_t size = sizeof(Point) * totalGrid;
Point ** d_memory;
cudaMalloc((void **)&d_memory, size);
/*
for(int i=0; i<totalGrid; i++){
printf("%d\n",i);
cudaMalloc((void **)&d_memory[i], sizeof(Point));
}*/
dim3 bs(16,8,8);
kernel1<<<6249, bs>>>(d_memory, totalGrid);
cudaCheckError();
cudaDeviceSynchronize();
kernel2<<<1,1>>>(d_memory, totalGrid);
cudaCheckError();
cudaFree(d_memory);
return 0;
}
这是我用来编译代码的
nvcc -arch=sm_20 test.cu
我相信你的问题是
Point **d_memory;
应该是
Point *d_memory;
并且您不需要转换为 void **
,您的代码中需要它,因为传递的指针是 Point ***
而不是 Point **
.
请注意,cudaMalloc()
将分配连续的内存,Point **
建议您需要一个指针数组,我相信您需要这样的东西
Point **d_memory;
cudaMalloc((void **)&d_memory, rows);
for (row = 0 ; row < rows ; ++row)
cudaMalloc(&d_memory[row], columns * sizeof(Point));
但是,您需要检查以 d_memory
作为参数的其他对象是否会相应地处理 d_memory
。
此外,cudaMalloc()
returns cudaSuccess
当分配成功时,您永远不会检查它。
我正在尝试使用指向我在内核中创建的结构的指针来初始化内存中的数组。这是我到目前为止的代码,我不知道我做错了什么。如果我尝试对数组中的每个项目执行 cudaMalloc,则会出现分段错误,如果我不这样做,则会出现 "unspecified launch failure" 错误。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int status;
int location;
double distance;
} Point;
//Macro for checking cuda errors following a cuda launch or api call
#define cudaCheckError() {\
cudaError_t e=cudaGetLastError();\
if(e!=cudaSuccess) {\
printf("\nCuda failure %s:%d: '%s'\n",__FILE__,__LINE__,cudaGetErrorString(e));\
exit(0); \
}\
}
__global__ void kernel1(Point** d_memory, int limit){
int idx = blockIdx.x * blockDim.x * blockDim.y * blockDim.z
+ threadIdx.z * blockDim.y * blockDim.x
+ threadIdx.y * blockDim.x + threadIdx.x;
if(idx < limit) {
Point* pt = ( Point *) malloc( sizeof(Point) );
pt->distance = 10;
pt->location = -1;
pt->status = -1;
d_memory[idx] = pt;
}
}
__global__ void kernel2(Point** d_memory, int limit){
int i;
for (i=0; i<limit;i++){
printf("%f \n",d_memory[i]->distance);
}
}
int main(int argc, char *argv[])
{
int totalGrid = 257*193*129;
size_t size = sizeof(Point) * totalGrid;
Point ** d_memory;
cudaMalloc((void **)&d_memory, size);
/*
for(int i=0; i<totalGrid; i++){
printf("%d\n",i);
cudaMalloc((void **)&d_memory[i], sizeof(Point));
}*/
dim3 bs(16,8,8);
kernel1<<<6249, bs>>>(d_memory, totalGrid);
cudaCheckError();
cudaDeviceSynchronize();
kernel2<<<1,1>>>(d_memory, totalGrid);
cudaCheckError();
cudaFree(d_memory);
return 0;
}
这是我用来编译代码的
nvcc -arch=sm_20 test.cu
我相信你的问题是
Point **d_memory;
应该是
Point *d_memory;
并且您不需要转换为 void **
,您的代码中需要它,因为传递的指针是 Point ***
而不是 Point **
.
请注意,cudaMalloc()
将分配连续的内存,Point **
建议您需要一个指针数组,我相信您需要这样的东西
Point **d_memory;
cudaMalloc((void **)&d_memory, rows);
for (row = 0 ; row < rows ; ++row)
cudaMalloc(&d_memory[row], columns * sizeof(Point));
但是,您需要检查以 d_memory
作为参数的其他对象是否会相应地处理 d_memory
。
此外,cudaMalloc()
returns cudaSuccess
当分配成功时,您永远不会检查它。