2012-04-29 21 views
31

質問は次のとおりです。Cudaカーネルでクラス "ベクトル"を使用する方法はありますか?試してみると、次のエラーが表示されます。CUDAデバイスコードでstd :: vectorを使用する

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

グローバルセクションにはベクターを使用する方法がありますか? は、私は最近、次のことを試してみました:

  1. オープンクーダC/C++
  2. の変化にデバイスへのコード」の値を行く
  3. は、プロジェクトのプロパティに移動し、新たなクーダプロジェクトを作成しますこの値に設定するには、次の値を設定します。 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::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; 
    } 
}; 
関連する問題