2012-04-29 3 views
31

Вопрос в том, что: существует ли способ использования класса «вектор» в ядрах Cuda? Когда я пытаюсь, я получаю следующую ошибку:Использование std :: vector в коде устройства CUDA

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. изменить значение в «Кодексе Generation ": compute_20, sm_20

........ после этого я смог использовать printf стандартной библиотечной функции в моем ядре Cuda.

Есть ли способ использовать стандартный класс библиотеки vector в том, как printf поддерживается в коде ядра? Это пример использования 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 в коде устройства, вы должны использовать массив.

12

В толчке библиотеки cuda вы можете использовать thrust::device_vector<classT> для определения вектора на устройстве, а передача данных между вектором STL-устройства и вектором устройства очень проста. вы можете обратиться к этой полезной ссылке: http://docs.nvidia.com/cuda/thrust/index.html, чтобы найти полезные примеры.

-1

Я думаю, что вы можете реализовать вектор устройства самостоятельно, потому что CUDA поддерживает динамическое выделение памяти в кодах устройств. Оператор new/delete также поддерживается. Вот очень простой прототип вектора устройства в 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; 
    } 
}; 
Смежные вопросы