问题是:有没有办法在Cuda内核中使用类“vector”?当我尝试时,我收到以下错误:
error : calling a host function("std::vector<int, std::allocator<int> > ::push_back") from a __device__/__global__ function not allowed
那么有一种方法可以在全局部分使用向量吗? 我最近尝试了以下内容:
........之后我能够在我的Cuda内核中使用printf标准库函数。
有没有办法在内核代码中支持printf的方式使用标准库类vector
?这是在内核代码中使用printf的一个例子:
// this code only to count the 3s in an array using Cuda
//private_count is an array to hold every thread's result separately
__global__ void countKernel(int *a, int length, int* private_count)
{
printf("%d\n",threadIdx.x); //it's print the thread id and it's working
// vector<int> y;
//y.push_back(0); is there a possibility to do this?
unsigned int offset = threadIdx.x * length;
int i = offset;
for( ; i < offset + length; i++)
{
if(a[i] == 3)
{
private_count[threadIdx.x]++;
printf("%d ",a[i]);
}
}
}
答案 0 :(得分:22)
您无法在CUDA中使用STL,但您可以使用Thrust library来执行您想要的操作。否则只需将矢量内容复制到设备上并正常操作即可。
答案 1 :(得分:14)
在cuda图书馆中,您可以使用thrust::device_vector<classT
&gt;在器件上定义矢量,主机STL矢量和器件矢量之间的数据传输非常简单。你可以参考这个有用的链接:http://docs.nvidia.com/cuda/thrust/index.html来找到一些有用的例子。
答案 2 :(得分:8)
你不能在设备代码中使用std::vector
,你应该使用数组。
答案 3 :(得分:2)
我认为您可以自己实现设备向量,因为CUDA支持设备代码中的动态内存分配。还支持运营商新/删除。这是CUDA中一个非常简单的设备向量原型,但确实有效。它尚未经过充分测试。
template<typename T>
class LocalVector
{
private:
T* m_begin;
T* m_end;
size_t capacity;
size_t length;
__device__ void expand() {
capacity *= 2;
size_t tempLength = (m_end - m_begin);
T* tempBegin = new T[capacity];
memcpy(tempBegin, m_begin, tempLength * sizeof(T));
delete[] m_begin;
m_begin = tempBegin;
m_end = m_begin + tempLength;
length = static_cast<size_t>(m_end - m_begin);
}
public:
__device__ explicit LocalVector() : length(0), capacity(16) {
m_begin = new T[capacity];
m_end = m_begin;
}
__device__ T& operator[] (unsigned int index) {
return *(m_begin + index);//*(begin+index)
}
__device__ T* begin() {
return m_begin;
}
__device__ T* end() {
return m_end;
}
__device__ ~LocalVector()
{
delete[] m_begin;
m_begin = nullptr;
}
__device__ void add(T t) {
if ((m_end - m_begin) >= capacity) {
expand();
}
new (m_end) T(t);
m_end++;
length++;
}
__device__ T pop() {
T endElement = (*m_end);
delete m_end;
m_end--;
return endElement;
}
__device__ size_t getSize() {
return length;
}
};