2012-04-29 137 views
31

问题是:有没有办法在Cuda内核中使用类“vector”?当我尝试我得到以下错误:在CUDA设备代码中使用std :: vector

error : calling a host function("std::vector<int, std::allocator<int> > ::push_back") from a __device__/__global__ function not allowed 

所以有办法在全球部分使用一个向量? 我最近尝试以下操作:

  1. 创建一个新的Cuda项目
  2. 进入项目的性质
  3. 开放CUDA C/C++
  4. 进入设备
  5. 变化“代码值代“设置为这个值: compute_20,sm_20

........之后,我能够使用我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]); 
     } 
    } 
} 
+3

+1完全合法的问题(不知道为什么它被否决。很不幸,答案是目前还没有。 – harrism

回答

20

您不能使用STL的CUDA,但是你可以使用Thrust library做你想做什么。否则,只需将矢量的内容复制到设备并正常操作即可。

+3

我不明白这是怎么应该帮助,因为'推力:: device_vector'不能在内核中使用,无论是。 – thatWiseGuy

7

你不能在设备代码中使用std::vector,你应该使用array来代替。

12

在CUDA库推力,可以使用thrust::device_vector<classT>上定义装置的载体,以及宿主STL矢量和设备矢量之间的数据传输是很简单的。你可以参考这个有用的链接:http://docs.nvidia.com/cuda/thrust/index.html找到一些有用的例子。

-1

我想你可以自己实现一个设备向量,因为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; 
    } 
};