CUDA中结构的简单操作:分段故障
这是我第一次在CUDA中实现结构。在下面的程序中,我将结构复制到GPU,并对数据执行基本操作,然后将结果复制回主机CUDA中结构的简单操作:分段故障,cuda,Cuda,这是我第一次在CUDA中实现结构。在下面的程序中,我将结构复制到GPU,并对数据执行基本操作,然后将结果复制回主机 #include<stdio.h> inline cudaError_t checkCuda(cudaError_t result) { #if defined(DEBUG) || defined(_DEBUG) if (result != cudaSuccess) { fprintf(stderr, "CUDA Run
#include<stdio.h>
inline cudaError_t checkCuda(cudaError_t result)
{
#if defined(DEBUG) || defined(_DEBUG)
if (result != cudaSuccess) {
fprintf(stderr, "CUDA Runtime Error: %sn", cudaGetErrorString(result));
assert(result == cudaSuccess);
}
#endif
return result;
}
typedef struct myStruct {
int* a;
int b;
}MyStruct;
__global__ void structOperation(MyStruct *d_data){
int idx = threadIdx.x;
d_data->a[idx] += 10;
}
int main(){
MyStruct *h_data, *d_data, *out_data;
size_t structSize = sizeof(MyStruct);
size_t intSize = sizeof(int);
h_data = (MyStruct *) malloc(structSize * 1);
h_data->b = 32;
h_data->a = (int *)malloc(intSize * h_data->b);
out_data = (MyStruct *) malloc(structSize * 1);
out_data->b = 32;
out_data->a = (int *)malloc(intSize * out_data->b);
for(int i = 0; i<32; i++){
h_data->a[i] = i;
}
//Memory allocation for the Struct
checkCuda(cudaMalloc(&d_data, sizeof(MyStruct) * 1));
checkCuda(cudaMalloc(&(d_data->a), sizeof(int) * 32));
checkCuda(cudaMemcpy(&d_data, &h_data, sizeof(MyStruct) * 1, cudaMemcpyHostToDevice));
checkCuda(cudaMemcpy(&(d_data->a), &(h_data->a), sizeof(int) * 32, cudaMemcpyHostToDevice));
structOperation<<<1,32>>>(d_data);
checkCuda(cudaMemcpy(&out_data, &d_data, sizeof(myStruct) * 1, cudaMemcpyDeviceToHost));
//cudaMemcpy(&(out_data->a), &(d_data->a), sizeof(int) * d_data->b, cudaMemcpyDeviceToHost);
printf("\nDataElements : ");
for(int i = 0; i<32; i++){
printf(" %d",out_data->a[i]);
}
printf("\n");
}
#包括
内联cudaError\u t checkCuda(cudaError\u t结果)
{
#如果已定义(调试)| |已定义(_调试)
如果(结果!=cudaSuccess){
fprintf(stderr,“CUDA运行时错误:%sn”,cudaGetErrorString(结果));
断言(结果==cudaSuccess);
}
#恩迪夫
返回结果;
}
typedef结构myStruct{
int*a;
int b;
}我的结构;
__全局无效结构操作(MyStruct*d_数据){
int idx=threadIdx.x;
d_数据->a[idx]+=10;
}
int main(){
MyStruct*h_数据、*d_数据、*out_数据;
size\u t structSize=sizeof(MyStruct);
size\u t intSize=sizeof(int);
h_data=(MyStruct*)malloc(structSize*1);
h_数据->b=32;
h_数据->a=(int*)malloc(intSize*h_数据->b);
out_data=(MyStruct*)malloc(structSize*1);
输出数据->b=32;
out\u data->a=(int*)malloc(intSize*out\u data->b);
对于(int i=0;ia[i]=i;
}
//结构的内存分配
检查CUDA(cudaMalloc(&d_数据,sizeof(MyStruct)*1);
检查CUDA(cudaMalloc(&(d_数据->a),sizeof(int)*32);
检查CUDA(cudaMemcpy(&d_数据,&h_数据,sizeof(MyStruct)*1,cudaMemcpyHostToDevice));
选中CUDA(cudaMemcpy(&(d_数据->a),&(h_数据->a),sizeof(int)*32,cudaMemcpyHostToDevice));
结构操作(d_数据);
选中CUDA(cudaMemcpy(&out_数据,&d_数据,sizeof(myStruct)*1,cudaMemcpyDeviceToHost));
//CUDAMCPY(&(out_数据->a),&(d_数据->a),sizeof(int)*d_数据->b,CUDAMCPydeviceToHost);
printf(“\n数据元素:”);
对于(int i=0;ia[i]);
}
printf(“\n”);
}
由于执行,我得到了“分段错误”。我猜我操作的结构不正确。正确的实现方法是什么?提供的代码中有几个无效的内存访问
d_data->a
访问设备内存(使用cudamaloc
分配)将导致未定义的行为(分段故障等)cudaMemcpy
将指针作为参数,而不是指针的地址。因此cudaMemcpy(&d\u数据,&h\u数据…
应替换为cudaMemcpy(d\u数据,h\u数据…
)MyStruct temp
)cudamaloc(&temp.a,bytes)
)cudamaloc(&d_数据,sizeof(MyStruct)
)cudaMemcpy(d_数据,&temp,sizeof(MyStruct),cudaMemcpyHostToDevice)
)d_data->a
的内容时,temp.a
也会被修改,因为它们实际上指向设备上的相同内存位置
最终的主要功能如下所示:
int main(){
MyStruct *h_data, *d_data, *out_data;
size_t structSize = sizeof(MyStruct);
size_t intSize = sizeof(int);
h_data = (MyStruct *) malloc(structSize * 1);
h_data->b = 32;
h_data->a = (int *)malloc(intSize * h_data->b);
out_data = (MyStruct *) malloc(structSize * 1);
out_data->b = 32;
out_data->a = (int *)malloc(intSize * out_data->b);
for(int i = 0; i<32; i++){
h_data->a[i] = i;
}
//Create temporary MyStruct object on host and allocate memory to its member "a" on device
MyStruct temp;
temp.b = h_data->b;
checkCuda(cudaMalloc(&temp.a, 32 * sizeof(int)));
//Copy host data to temp.a
checkCuda(cudaMemcpy(temp.a, h_data->a, 32 * sizeof(int), cudaMemcpyHostToDevice));
//Memory allocation for the device MyStruct
checkCuda(cudaMalloc(&d_data, sizeof(MyStruct) * 1));
//Copy actual object to device
checkCuda(cudaMemcpy(d_data, &temp, sizeof(MyStruct) * 1, cudaMemcpyHostToDevice));
structOperation<<<1,32>>>(d_data);
//temp.a will be updated after kernel launch
checkCuda(cudaMemcpy(out_data->a, temp.a, 32 * sizeof(int), cudaMemcpyDeviceToHost));
printf("\nDataElements : ");
for(int i = 0; i<32; i++)
{
printf(" %d",out_data->a[i]);
}
printf("\n");
checkCuda(cudaFree(temp.a));
checkCuda(cudaFree(d_data));
free(h_data->a);
free(out_data->a);
free(h_data);
free(out_data);
}
intmain(){
MyStruct*h_数据、*d_数据、*out_数据;
size\u t structSize=sizeof(MyStruct);
size\u t intSize=sizeof(int);
h_data=(MyStruct*)malloc(structSize*1);
h_数据->b=32;
h_数据->a=(int*)malloc(intSize*h_数据->b);
out_data=(MyStruct*)malloc(structSize*1);
输出数据->b=32;
out\u data->a=(int*)malloc(intSize*out\u data->b);
对于(int i=0;ia[i]=i;
}
//在主机上创建临时MyStruct对象,并将内存分配给设备上的成员“a”
我的结构温度;
温度b=h_数据->b;
检查CUDA(cudaMalloc(&temp.a,32*sizeof(int));
//将主机数据复制到临时a
选中CUDA(cudaMemcpy(温度a,h_数据->a,32*sizeof(int),cudaMemcpyHostToDevice));
//设备MyStruct的内存分配
检查CUDA(cudaMalloc(&d_数据,sizeof(MyStruct)*1);
//将实际对象复制到设备
检查CUDA(cudaMemcpy(数据、温度和大小(MyStruct)*1,cudaMemcpyHostToDevice));
结构操作(d_数据);
//temp.a将在内核启动后更新
选中CUDA(cudaMemcpy(输出数据->a,温度a,32*sizeof(int),cudaMemcpyDeviceToHost));
printf(“\n数据元素:”);
对于(int i=0;ia[i]);
}
printf(“\n”);
检查CUDA(cudaFree(临时a));
检查CUDA(cudaFree(d_数据));
免费(h_数据->a);
自由(输出数据->a);
免费(h_数据);
免费(out_数据);
}
用于查找哪个CUDA呼叫failed@m.s.添加了cudaError检查。这实际上是一些我无法理解的内存冲突问题。仍然会给我分段错误。什么错误消息?在哪行?您的问题可能会被标记为重复。请参阅和。当您执行此操作时,您正在从主机访问设备内存是:&(d_data->a)
中的cudamaloc
和cudaMemcpy
调用。现在这就提出了几个问题。1.结构对象的成员(此处为temp)如何在设备内存中声明其内存,尽管对象在主机内存中声明?它甚至不是指向结构对象的指针,而是实际的结构对象。2.为什么我们不能直接执行从主机到设备的结构复制,只执行h_数据和d_数据之间的数据传输,而不使用temp?@sandeep.ganage的成员主机对象只是一个简单的指针。当我们分配设备内存时,指针本身驻留在主机上,但它所指向的内存区域存在于设备上。要将设备内存分配给没有构造函数的结构的成员,结构对象应该驻留在主机上,否则我们如何访问其成员对于分配?结构类型(指针或对象)与其成员的显式内存分配无关。@sandeep.ganage….分配设备内存(u