2012-04-29 7 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는 C/C++
  2. 변화를 장치에 코드 "의 값을 이동
  3. 프로젝트의 속성으로 이동 새로운 CUDA는 프로젝트를 생성 생성 "이이 값으로 설정됩니다 : compute_20, sm_20

....... 그 후 나는 내 Cuda 커널의 printf 표준 라이브러리 함수.

printf가 커널 코드에서 지원되는 방식에 표준 라이브러리 클래스 vector을 사용하는 방법이 있습니까?

// 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

당신은 CUDA에서 STL을 사용할 수 없습니다,하지만 당신은 당신이 원하는 일을하기 위해 Thrust library를 사용할 수 있습니다 : 이것은 커널 코드에서의 printf를 사용하는 예입니다. 그렇지 않으면 벡터의 내용을 장치에 복사하고 정상적으로 작동합니다.

+3

'추력 :: device_vector' 될 수 없기 때문에 나는이가 도움을하도록되어 표시되지 않습니다 커널 내부에서도 사용됩니다. – thatWiseGuy

7

기기 코드에 std::vector을 사용할 수 없으므로 대신 배열을 사용해야합니다.

12

cuda 라이브러리에서 thrust를 사용하면 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; 
    } 
};