C++ 如何在cuda程序中实现[]运算符重载?

C++ 如何在cuda程序中实现[]运算符重载?,c++,cuda,C++,Cuda,我正在Cuda中实现一个device\u vector,我从著名的图书馆中汲取了一些想法 现在,为了访问和修改设备向量(v)中的元素,我需要执行v[N]=x。为此,我需要重载[]操作符 这是用于重载[]运算符的代码: T& operator[] (unsigned int index) { if (index >= numEle) return ptr[0]; else return ptr[index]; } 问题是:要修改设备内

我正在Cuda中实现一个
device\u vector
,我从著名的图书馆中汲取了一些想法

现在,为了访问和修改
设备向量(v)中的元素,我需要执行v[N]=x。为此,我需要重载[]操作符

这是用于重载[]运算符的代码:

T& operator[] (unsigned int index)
{
    if (index >= numEle)
        return ptr[0];
    else
        return ptr[index];
}
问题是:要修改设备内存中的任何内存位置,我们需要进行Cuda内核调用,而Cuda内核调用无法返回任何内容。

就[]重载而言,它返回对要修改的元素的引用

我们如何为Cuda内核做到这一点


注意:我知道推力库以某种方式做到了这一点,但我无法理解它是如何做到的。

注释有很好的指针,但作为一个例子,您可以创建一个对象,允许您使用
[]
操作符直接写入CUDA数组(或执行您选择的任何其他操作):

输出:

从设备获取:8
从设备获取:7
在设备中设置:6 0
内置设备:5 0

其思想是,
运算符[]
不返回引用,而是返回一个临时对象,该对象能够处理“读取”(使用转换运算符)和“写入”(使用赋值运算符)


(第二个重载用于允许链式赋值,因为如果不首先从
unsigned int
赋值,则不会自动拾取第一个重载。)

您可以返回一个临时对象,该对象允许转换到
unsigned int
@Kos并从中进行赋值。我无法理解…请您提供更多详细信息。此函数应该在主机或设备上运行吗?将从主机使用运算符。但是要修改设备中的内存,我们需要进行内核调用。这不是启动的内核名称。我不反对推力可以使用内核启动来完成各种事情,但是在您的测试用例中,
nvprof
输出中的内核启动行位于
[CUDA memcpy DtoH]
行之前。您正在见证的内核启动发生在
推力::设备\u向量的实例化时。
[CUDA memcpy DtoH]
是nvprof报告发生
cudaMemcpy
操作的方式(不是内核启动),该操作的指定方向是
cudaMemcpyDeviceToHost
(这是您的
v[N]
取消引用的结果)。这非常有用。非常感谢,先生。
struct CudaVector {

    unsigned int get(unsigned int index) {
        cout << "Get from device: " << index << endl;
        return 0; // TODO read actual value
    }
    void set(unsigned int index, unsigned int value) {
        cout << "Set in device: " << index << " " << value << endl;
        // TODO write actual value
    }

    struct Item {
        CudaVector& vector;
        unsigned int index;
        operator unsigned int() const {
            return vector.get(index);
        }       
        unsigned int operator=(unsigned int other) {
            vector.set(index, other);
            return other;
        }
        unsigned int operator=(const Item& other) {
            return (*this = static_cast<unsigned int>(other));
        }
    };

    Item operator[](unsigned int index) {
        return Item{*this, index};
    }
};
CudaVector vector;
unsigned int foo = vector[8];
vector[5] = vector[6] = vector[7];