2012-04-29 1 views
31

La domanda è: esiste un modo per utilizzare il vettore di classe nei kernel Cuda? Quando provo ottengo il seguente errore:Uso di std :: vector nel codice dispositivo CUDA

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

Quindi c'è un modo per utilizzare un vettore nella sezione globale? Recentemente ho provato la seguente:

  1. creare un nuovo progetto Cuda
  2. andare alle proprietà del progetto
  3. aperto Cuda C/C++
  4. andare al dispositivo
  5. variazione del valore in "Codice Generazione "da impostare su questo valore: compute_20, sm_20

........ dopo che sono stato in grado di utilizzare il funzione di libreria standard di printf nel mio kernel Cuda.

esiste un modo per utilizzare la classe di libreria standard vector nel modo in cui printf è supportato nel codice del kernel? Questo è un esempio di utilizzo di printf nel codice del kernel:

// 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 domanda perfettamente legittima (non so perché è stato bocciato. Purtroppo la risposta è attualmente. – harrism

risposta

20

Non è possibile utilizzare lo STL in CUDA, ma si può essere in grado di utilizzare il Thrust library per fare quello che vuoi. Altrimenti copia semplicemente il contenuto del vettore sul dispositivo e fallo normalmente.

+3

Io non vedo come questo dovrebbe aiutare, perché un 'di spinta :: device_vector' non può essere usato anche all'interno dei kernel. – thatWiseGuy

7

non è possibile utilizzare std::vector nel codice del dispositivo, è necessario utilizzare matrice.

12

Nella libreria cuda, è possibile utilizzare thrust::device_vector<classT> per definire un vettore sul dispositivo e il trasferimento dei dati tra il vettore STL host e il vettore del dispositivo è molto semplice. puoi fare riferimento a questo link utile: http://docs.nvidia.com/cuda/thrust/index.html per trovare alcuni esempi utili.

-1

Penso che sia possibile implementare un vettore dispositivo da soli, poiché CUDA supporta l'allocazione dinamica della memoria nei codici dispositivo. Sono supportati anche gli operatori new/delete. Ecco un prototipo di vettore di dispositivo estremamente semplice in CUDA, ma funziona. Non è stato testato a sufficienza.

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; 
    } 
};