CUDAでのstd ::ベクトルを使用する方法が明らかにされていませんが、私は私自身のVectorクラスを設計した:ベクトルへの対処 - cudaMemcpyDeviceToHost
#ifndef VECTORHEADERDEF
#define VECTORHEADERDEF
#include <cmath>
#include <iostream>
#include <cassert>
template <typename T>
class Vector
{
private:
T* mData; // data stored in vector
int mSize; // size of vector
public:
Vector(const Vector& otherVector); // Constructor
Vector(int size); // Constructor
~Vector(); // Desructor
__host__ __device__ int GetSize() const; // get size of the vector
T& operator[](int i); // see element
// change element i
__host__ __device__ void set(size_t i, T value) {
mData[i] = value;
}
template <class S> // output vector
friend std::ostream& operator<<(std::ostream& output, Vector<S>& v);
};
// Overridden copy constructor
// Allocates memory for new vector, and copies entries of other vector into it
template <typename T>
Vector<T>::Vector(const Vector& otherVector)
{
mSize = otherVector.GetSize();
mData = new T [mSize];
for (int i=0; i<mSize; i++)
{
mData[i] = otherVector.mData[i];
}
}
// Constructor for vector of a given size
// Allocates memory, and initialises entries to zero
template <typename T>
Vector<T>::Vector(int size)
{
assert(size > 0);
mSize = size;
mData = new T [mSize];
for (int i=0; i<mSize; i++)
{
mData[i] = 0.0;
}
}
// Overridden destructor to correctly free memory
template <typename T>
Vector<T>::~Vector()
{
delete[] mData;
}
// Method to get the size of a vector
template <typename T>
__host__ __device__ int Vector<T>::GetSize() const
{
return mSize;
}
// Overloading square brackets
// Note that this uses `zero-based' indexing, and a check on the validity of the index
template <typename T>
T& Vector<T>::operator[](int i)
{
assert(i > -1);
assert(i < mSize);
return mData[i];
}
// Overloading the assignment operator
template <typename T>
Vector<T>& Vector<T>::operator=(const Vector& otherVector)
{
assert(mSize == otherVector.mSize);
for (int i=0; i<mSize; i++)
{
mData[i] = otherVector.mData[i];
}
return *this;
}
// Overloading the insertion << operator
template <typename T>
std::ostream& operator<<(std::ostream& output, Vector<T>& v) {
for (int i=0; i<v.mSize; i++) {
output << v[i] << " ";
}
return output;
}
私の主な機能 - 私はちょうどにベクトルを渡しますデバイス、それを変更し、それをバックパス - 次のように(単にテスト目的のために設計されたカーネルで)です:
#include <iostream>
#include "Vector.hpp"
__global__ void alpha(Vector<int>* d_num)
{
int myId = threadIdx.x + blockDim.x * blockIdx.x;
d_num->set(0,100);
d_num->set(2,11);
}
int main()
{
Vector<int> num(10);
for (int i=0; i < num.GetSize(); ++i) num.set(i,i); // initialize elements to 0:9
std::cout << "Size of vector: " << num.GetSize() << "\n";
std::cout << num << "\n"; // print vector
Vector<int>* d_num;
// allocate global memory on the device
cudaMalloc((void **) &d_num, num.GetSize()*sizeof(int));
// copy data from host memory to the device memory
cudaMemcpy(d_num, &num[0], num.GetSize()*sizeof(int), cudaMemcpyHostToDevice);
// launch the kernel
alpha<<<1,100>>>(d_num);
// copy the modified array back to the host, overwriting the contents of h_arr
cudaMemcpy(num, &d_num[0], num.GetSize()*sizeof(int), cudaMemcpyDeviceToHost);
std::cout << num << "\n";
// free GPU memory allocation and exit
cudaFree(d_num);
return 0;
}
私が遭遇した問題はcudaMemcpyDeviceToHostです。実際には、出力から見られるように、デバイスベクトルをnumベクトルにコピーしません。
どうすれば対応できますか? (明示してください、私はCUDAをかなり新しくしています)。これはないだろう
cudaMemcpy(d_num, &num[0], num.GetSize()*sizeof(int), cudaMemcpyHostToDevice);
^^^^^^^
:あなたのVector
オブジェクトの名前は、そのへのポインタではありません
cudaMemcpy(num, &d_num[0], num.GetSize()*sizeof(int), cudaMemcpyDeviceToHost);
^^^
ありがとう、ロバート。あなたの答えはとてもいいです。カーネルは単なる実験的なものでした。 推力ベクトルは同様の設計ですか? 型の変数を宣言して(デバイスに渡すことはできますか?)Vector
推力ベクトルには同様の設計はありません。推力には、ホストベクトルと別のデバイスベクトルクラスがあります。ホストとデバイスのストレージを1つのクラスにまとめません。しかし、デザインは(IMO)かなりきれいで、明らかにあなたがここにあるよりもはるかに洗練されています。推力ベクトルの詳細については、推力[クイックスタートガイド](https://github.com/thrust/thrust/wiki/Quick-Start-Guide)をお試しください。また、推力はオープンソースです。Nietherここの方法や推力(デバイス)ベクトルは簡単にベクトルのベクトルを扱うことができますが、より単純なオブジェクトのベクトルも可能です。 –