問題は、Cudaカーネルでクラス「ベクター」を使用する方法はありますか?しようとすると、次のエラーが表示されます。
error : calling a Host function("std::vector<int, std::allocator<int> > ::Push_back") from a __device__/__global__ function not allowed
グローバルセクションでベクトルを使用する方法はありますか?私は最近、以下を試しました:
........その後、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]);
}
}
}
CUDAでSTLを使用することはできませんが、 Thrust library を使用して目的の操作を実行できる場合があります。それ以外の場合は、ベクターの内容をデバイスにコピーして、通常どおり操作します。
Cudaライブラリスラストでは、thrust::device_vector<classT
>を使用してデバイス上のベクトルを定義でき、ホストSTLベクトルとデバイスベクトル間のデータ転送は非常に簡単です。次の便利なリンクを参照してください: http://docs.nvidia.com/cuda/thrust/index.html .
デバイスコードでstd::vector
を使用することはできません。代わりに配列を使用する必要があります。
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;
}
};