La question est la suivante: existe-t-il un moyen d'utiliser la classe "vector" dans les noyaux Cuda? Lorsque j'essaie, j'obtiens l'erreur suivante:
error : calling a Host function("std::vector<int, std::allocator<int> > ::Push_back") from a __device__/__global__ function not allowed
Donc, existe-t-il un moyen d'utiliser un vecteur dans la section globale? J'ai récemment essayé ce qui suit:
........ après cela, j'ai pu utiliser la fonction de bibliothèque standard printf dans mon noyau Cuda.
existe-t-il un moyen d'utiliser la classe de bibliothèque standard vector
dans la façon dont printf est pris en charge dans le code du noyau? Voici un exemple d'utilisation de printf dans le code du noyau:
// 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]);
}
}
}
Vous ne pouvez pas utiliser la STL dans CUDA, mais vous pourrez peut-être utiliser la bibliothèque Thrust pour faire ce que vous voulez. Sinon, copiez simplement le contenu du vecteur sur l'appareil et utilisez-le normalement.
Dans la poussée de la bibliothèque cuda, vous pouvez utiliser thrust::device_vector<classT
> pour définir un vecteur sur le périphérique, et le transfert de données entre le vecteur Host STL et le vecteur de périphérique est très simple. vous pouvez vous référer à ce lien utile: http://docs.nvidia.com/cuda/thrust/index.html pour trouver des exemples utiles.
vous ne pouvez pas utiliser std::vector
dans le code du périphérique, vous devez utiliser un tableau à la place.
Je pense que vous pouvez implémenter vous-même un vecteur de périphérique, car CUDA prend en charge l'allocation de mémoire dynamique dans les codes de périphérique. L'opérateur new/delete est également pris en charge. Voici un prototype extrêmement simple de vecteur de périphérique dans CUDA, mais cela fonctionne. Il n'a pas été suffisamment testé.
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;
}
};