web-dev-qa-db-ja.com

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. 「コード生成」の値を変更して、次の値に設定します:compute_20、sm_20

........その後、Cudaカーネルでprintf標準ライブラリ関数を使用することができました。

カーネルコードでprintfがサポートされる方法で標準ライブラリクラスvectorを使用する方法はありますか?これは、カーネルコードで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]);
        }
    }   
}
37
Yasser

CUDAでSTLを使用することはできませんが、 Thrust library を使用して目的の操作を実行できる場合があります。それ以外の場合は、ベクターの内容をデバイスにコピーして、通常どおり操作します。

22
Edvard Pedersen

Cudaライブラリスラストでは、thrust::device_vector<classT>を使用してデバイス上のベクトルを定義でき、ホストSTLベクトルとデバイスベクトル間のデータ転送は非常に簡単です。次の便利なリンクを参照してください: http://docs.nvidia.com/cuda/thrust/index.html .

14
Zhong Hu

デバイスコードでstd::vectorを使用することはできません。代わりに配列を使用する必要があります。

8
yyfn

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;
    }
};
2
Robin Lew