C++ 如何在cuda程序中实现[]运算符重载?
我正在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]; } 问题是:要修改设备内
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];