2012-04-29 13 views
31

Pytanie brzmi: czy istnieje sposób użycia klasy "wektor" w jądrze Cuda? Gdy próbuję, pojawia się następujący błąd:Używanie std :: vector w kodzie urządzenia CUDA

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

A więc sposób na wykorzystanie wektora w sekcji globalnej? Niedawno próbowałem następujące:

  1. utworzyć nowy projekt Cuda
  2. przejdź do właściwości projektu
  3. otwarty Cuda C/C++
  4. iść do urządzenia
  5. zmienić wartość w „Kodeksie Generacja ", aby ustawić tę wartość: compute_20, sm_20

........ po tym czasie mogłem użyć funkcja standardowej biblioteki printf w moim jądrze Cuda.

Czy istnieje sposób użycia standardowej biblioteki klasy vector w sposobie, w jaki printf jest obsługiwany w kodzie jądra? To jest przykład użycia printf w kodzie jądra:

// 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 doskonale legit pytanie (nie wiem, dlaczego został przegłosowany. Niestety odpowiedź jest jeszcze. – harrism

Odpowiedz

20

Nie można używać STL w CUDA, ale może być w stanie korzystać z Thrust library robić, co chcesz. W przeciwnym razie po prostu skopiuj zawartość wektora do urządzenia i normalnie działaj na nim.

+3

nie widzę jak to ma pomóc, bo 'pchnięcie :: device_vector' nie może być używane również w jądrze. – thatWiseGuy

7

Nie można używać std::vector w kodzie urządzenia, należy zamiast tego użyć tablicy.

12

Przy użyciu biblioteki cuda można użyć thrust::device_vector<classT> do zdefiniowania wektora na urządzeniu, a transfer danych między wektorem hosta STL a wektorem urządzenia jest bardzo prosty. możesz skorzystać z tego przydatnego linku: http://docs.nvidia.com/cuda/thrust/index.html, aby znaleźć przydatne przykłady.

-1

Myślę, że możesz zaimplementować wektor urządzeń samodzielnie, ponieważ CUDA obsługuje dynamiczne przydzielanie pamięci w kodach urządzeń. Operator new/delete są również obsługiwane. Oto niezwykle prosty prototyp wektora urządzenia w CUDA, ale działa. Nie zostało dostatecznie przetestowane.

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