C++ 通过复制将对象传递给CUDA内核会调用其析构函数并过早释放内存

C++ 通过复制将对象传递给CUDA内核会调用其析构函数并过早释放内存,c++,class,cuda,C++,Class,Cuda,我有一个GPUMatrix类,该类使用cudamalocmanaged分配数据: class GPUMatrix { public: GPUMatrix() { }; GPUMatrix(int rows, int cols, unsigned flags = 0) { cudaMallocManaged(data) ... }; ~GPUMatrix() { cudaFree(data) ... }; public: int rows = 0; int

我有一个
GPUMatrix
类,该类使用
cudamalocmanaged
分配
数据

class GPUMatrix
{
public:
    GPUMatrix() { };
    GPUMatrix(int rows, int cols, unsigned flags = 0) { cudaMallocManaged(data) ... };
    ~GPUMatrix() { cudaFree(data) ... };

public:
    int rows = 0;
    int cols = 0;
    float *data = nullptr;
};
GPU只能访问
数据
指针。因此,我这样定义mat mul内核(它获取对象的副本):


但是,在完成后调用
~GPUMatrix()
并释放内存。处理这个问题的最好方法是什么?我无法将指向
GPUMatrix
的指针或引用传递给内核,因为整个对象不是由
cudamalocmanaged
分配的,只有
数据
元素是。

析构函数始终删除
数据
指针。但是,默认复制构造函数将具有原始对象的
数据
指针的副本,它不能删除该副本

解决此问题的一种方法是修改类,使其保留一个标志,该标志表示
数据
指针是否属于该类并且需要删除。然后定义一个复制构造函数,该构造函数将相应地设置该标志


如果副本比原始对象长,则此方法存在潜在问题,并且还应添加移动构造函数。然后是复制赋值和移动赋值操作符。请参阅以获取更多信息。

不要在默认构造函数或析构函数中调用CUDA API当然我可以这样做,但是我必须有一个
Init
Release
对方法,对吗?并且必须记住给他们打电话,否则可能会导致内存泄漏,这似乎很不方便。或者你是在暗示什么?
__global__
void MatMulNaiveKernelMat(const GPUMatrix a, const GPUMatrix b, const GPUMatrix c)...