Object Cuda对象副本

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

我正在尝试将CUDA与对象一起使用,这是我编写的一个小测试代码,用于尝试一些东西,但我遇到了一个问题。当我对变量的设备版本执行任何操作时,将代码复制回主机会失败,并显示“cuda Error Ilegal Address”,但如果我只是将代码复制到设备并将其复制回主机,它就会工作。 如果我把打印件注释掉。。。行,这是有效的

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::首先感谢您的快速回答。阅读您的答案时出现了另一个问题,您说问题在于设备变量,但如果我删除设备关键字,我无法在全局函数中使用该变量。那么在这种情况下,正确的用法是什么?我用我的回答:“如果您使用一个普通的基于主机的指针,指向运行时创建的动态分配(无论如何,您都在这样做),然后通过内核参数将基于主机的指针传递给设备,那么您的方法将得到简化。”我明白了,再次感谢。我想,我开始了解一些事情了。