Object Cuda对象副本
我正在尝试将CUDA与对象一起使用,这是我编写的一个小测试代码,用于尝试一些东西,但我遇到了一个问题。当我对变量的设备版本执行任何操作时,将代码复制回主机会失败,并显示“cuda Error Ilegal Address”,但如果我只是将代码复制到设备并将其复制回主机,它就会工作。 如果我把打印件注释掉。。。行,这是有效的Object Cuda对象副本,object,cuda,memcpy,Object,Cuda,Memcpy,我正在尝试将CUDA与对象一起使用,这是我编写的一个小测试代码,用于尝试一些东西,但我遇到了一个问题。当我对变量的设备版本执行任何操作时,将代码复制回主机会失败,并显示“cuda Error Ilegal Address”,但如果我只是将代码复制到设备并将其复制回主机,它就会工作。 如果我把打印件注释掉。。。行,这是有效的 class A { public: int s; }; __device__ A *d_a; __global__ void MethodA() { pri
class A {
public:
int s;
};
__device__ A *d_a;
__global__ void MethodA() {
printf("%d\n", d_a->s);
}
int main() {
A *a = new A();
a->s = 10;
cudaError e;
e = cudaMalloc((void**)&d_a, sizeof(A));
e = cudaMemcpy(d_a, a, sizeof(A), cudaMemcpyHostToDevice);
MethodA << <1, 1 >> > ();
e = cudaMemcpy(a, d_a, sizeof(A), cudaMemcpyDeviceToHost);
std::cout << cudaGetErrorName(e) << std::endl;
delete(a);
std::getchar();
return 0;
}
A类{
公众:
int-s;
};
__装置A*d;
__全局无效方法A(){
printf(“%d\n”,d\u a->s);
}
int main(){
A*A=新的A();
a->s=10;
cudaError e;
e=cudamaloc((void**)和d_a,sizeof(a));
e=cudaMemcpy(d_a,a,sizeof(a),cudamemcpyhostodevice);
方法a>();
e=cudaMemcpy(a,d_a,sizeof(a),cudaMemcpyDeviceToHost);
std::cout使用\uuuu device\uuuu
变量会造成困难。该变量用于静态分配,在编译时已知
如果您使用一个普通的基于主机的指针,指向运行时创建的动态分配(您无论如何都要这样做),然后通过内核参数将该基于主机的指针传递给设备,那么您的方法将得到简化
您的方法存在一些问题:
$ cat t89.cu
#include <iostream>
#include <stdio.h>
class A {
public:
int s;
};
__global__ void MethodA(A *a) {
printf("%d\n", a->s);
}
int main() {
A *a = new A();
a->s = 10;
A *d_a; // an ordinary host-based pointer
cudaMalloc((void**)&d_a, sizeof(A)); //dynamic allocation created at runtime
cudaMemcpy(d_a, a, sizeof(A), cudaMemcpyHostToDevice);
MethodA << <1, 1 >> > (d_a); // passed to kernel via parameter
cudaMemcpy(a, d_a, sizeof(A), cudaMemcpyDeviceToHost);
std::cout << cudaGetErrorString(cudaGetLastError()) << std::endl;
cudaFree(d_a);
delete(a);
return 0;
}
$ nvcc -o t89 t89.cu
$ cuda-memcheck ./t89
========= CUDA-MEMCHECK
10
no error
========= ERROR SUMMARY: 0 errors
$
您正在使用不正确的API来修改\uuuu设备\uuu
变量。我们不使用cudaMemcpy
。我们使用cudaMemcpyToSymbol
等
不允许在主机代码中获取设备实体的地址:
e = cudaMalloc((void**)&d_a, sizeof(A));
^
cudamaloc
希望将分配的指针值存储在主机内存中,而不是设备内存中。它将指向设备内存中的某个位置,但应存储在主机变量中
如果要继续使用方法,请进行以下修改以使其正确:
$ cat t89.cu
#include <iostream>
#include <stdio.h>
class A {
public:
int s;
};
__device__ A *d_a;
__global__ void MethodA() {
printf("%d\n", d_a->s);
}
int main() {
A *a = new A();
a->s = 10;
A *temp_d_a;
cudaMalloc((void**)&temp_d_a, sizeof(A));
cudaMemcpy(temp_d_a, a, sizeof(A), cudaMemcpyHostToDevice);
cudaMemcpyToSymbol(d_a, &temp_d_a, sizeof(A *));
MethodA << <1, 1 >> > ();
cudaMemcpy(a, temp_d_a, sizeof(A), cudaMemcpyDeviceToHost);
std::cout << cudaGetErrorString(cudaGetLastError()) << std::endl;
cudaFree(temp_d_a);
delete(a);
return 0;
}
$ nvcc t89.cu -o t89
$ cuda-memcheck ./t89
========= CUDA-MEMCHECK
10
no error
========= ERROR SUMMARY: 0 errors
$
$cat t89.cu
#包括
#包括
甲级{
公众:
int-s;
};
__装置A*d;
__全局无效方法A(){
printf(“%d\n”,d\u a->s);
}
int main(){
A*A=新的A();
a->s=10;
A*临时性;
Cudamaloc((无效**)和temp_d_a,sizeof(a));
cudaMemcpy(温度a、a、尺寸(a)、cudaMemcpyHostToDevice);
cudaMemcpyToSymbol(d_a和temp_d_a,sizeof(a*);
方法a>();
cudaMemcpy(a、temp_d_a、sizeof(a)、cudamemcpydevicetoost);
标准::cout s=10;
A*d_A;//一个普通的基于主机的指针
cudamaloc((void**)&d_a,sizeof(a));//在运行时创建动态分配
cudaMemcpy(d_a,a,sizeof(a),cudamemcpyhostodevice);
MethodA>(d_a);//通过参数传递给内核
cudaMemcpy(a,d_a,sizeof(a),cudamemcpydevicetoost);
std::首先感谢您的快速回答。阅读您的答案时出现了另一个问题,您说问题在于设备变量,但如果我删除设备关键字,我无法在全局函数中使用该变量。那么在这种情况下,正确的用法是什么?我用我的回答:“如果您使用一个普通的基于主机的指针,指向运行时创建的动态分配(无论如何,您都在这样做),然后通过内核参数将基于主机的指针传递给设备,那么您的方法将得到简化。”我明白了,再次感谢。我想,我开始了解一些事情了。