2014-12-12 2 views
0

Есть ли способ скопировать двойной массив из Host в массив float на Device. Я не беспокоюсь о потере точности? У меня есть следующий случай:cudaMemcpy double array to float array

double* host = new[N]; 
... // Perform some calculations on host array 

float* device; 

cudaMalloc((void**) &device, N * sizeof(float)); 
cudaMemcpy(device, host, N * sizeof(float), cudaMemcpyHostToDevice); 

При попытке выше написанного кода я получаю ошибку недопустимый аргумент. Есть ли какое-либо решение для этого, кроме изменения массива хоста для float?

+1

Я не уверен, что вы понимаете, что делает memcpy или cudaMemcpy. Он выполняет байтовую двоичную копию без учета точности поплавка или двойной. Поэтому, даже если вы запустите код и не получите никаких ошибок, у вас будет мусор в вектор устройства. –

ответ

2

float - 4 байта, double - 8 байт. Вы не можете просто memcpy между несовместимыми типами, вы должны сначала преобразовать double s в float s.

Что-то вроде этого (я взял на себя смелость заменить сырые массивы стандартной библиотеки конструкций):

std::vector<double> host_double(N); 
// Perform some calculations on host array 

// Make a copy of the host vector, converting all doubles to floats 
std::vector<float> host_float(host_double.begin(), host_double.end()); 

// The rest is almost unchanged 
float* device; 

cudaMalloc((void**)&device, N * sizeof(float)); 
cudaMemcpy(device, host_float.data(), N * sizeof(float), cudaMemcpyHostToDevice); 

Однако, вы уверены, что получают выгоду от использования double вообще? Самая высокая точность всей вашей вычислительной цепочки будет в любом случае равной float.

+0

Его противная вещь, но это может быть единственный способ. Я не, но проект огромен, и он написан с использованием парных разрядов, даже несмотря на то, что точность поплавка очень хорошая. – Karpov