2016-04-12 3 views
3

В настоящее время я пытаюсь удалить часть громоздкого cudaMallocHost/cudaFreeHost из моего кода. Для этого я готов использовать только std :: vector, но мне абсолютно необходимо, чтобы базовая память была связана с типом памяти cuda.Странное поведение с использованием thrust experimental :: pinned_allocator в cuda

Но я столкнулся странное поведение с помощью thrust::system::cuda::experimental::pinned_allocator<> из библиотеки тяги:

//STL 
#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 

//CUDA 
#include <cuda_runtime.h> 
#include <thrust/device_vector.h> 
#include <thrust/transform.h> 
#include <thrust/system/cuda/experimental/pinned_allocator.h> 

#define SIZE 4 
#define INITVAL 2 
#define ENDVAL 4 

//Compile using nvcc ./main.cu -o test -std=c++11 
int main(int argc, char* argv[]) 
{ 
    // init host 
    std::vector<float,thrust::system::cuda::experimental::pinned_allocator<float> > hostVec(SIZE); 
    std::fill(hostVec.begin(),hostVec.end(),INITVAL); 

    //Init device 
    thrust::device_vector<float> thrustVec(hostVec.size()); 

    //Copy 
    thrust::copy(hostVec.begin(), hostVec.end(), thrustVec.begin()); 

    //std::cout << "Dereferencing values of the device, values should be "<< INITVAL << std::endl; 
    std::for_each(thrustVec.begin(),thrustVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;}); 
    std::cout << "------------------------" << std::endl; 

    //Do Stuff 
    thrust::transform(thrustVec.begin(), thrustVec.end(), thrust::make_constant_iterator(2), thrustVec.begin(), thrust::multiplies<float>()); 

    //std::cout << "Dereferencing values of the device, values should now be "<< ENDVAL << std::endl; 
    std::for_each(thrustVec.begin(),thrustVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;}); 
    std::cout << "------------------------" << std::endl; 

    //Copy back 
    thrust::copy(thrustVec.begin(), thrustVec.end(), hostVec.begin()); 

    //Synchronize 
    //cudaDeviceSynchronize(); //makes the weird behaviour to go away 

    //Check result 
    //std::cout << "Dereferencing values on the host, values should now be "<< ENDVAL << std::endl;//Also makes the weird behaviour to go away 

    std::for_each(hostVec.begin(),hostVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;}); 

    return EXIT_SUCCESS; 
} 

Который, в моей установке, дает:

val is 2 
val is 2 
val is 2 
val is 2 
------------------------ 
val is 4 
val is 4 
val is 4 
val is 4 
------------------------ 
val is 2 
val is 4 
val is 4 
val is 4 

Почему копии от устройства к хосту кажется потерпеть неудачу ? Однако Nvvp показывает прекрасную хронограмму с правильными значениями для копирования.

Кстати, я использую NVCC/cuda/thrust из пакета 7.5 и gcc (GCC) 4.8.5 с карточкой titanX.

Заранее благодарю вас за помощь.

+0

Я не могу воспроизвести это на любой платформе, к которой у меня есть доступ. Что произойдет, если вы добавите вызов синхронизации, прежде чем пытаться распечатать вектор после копирования экземпляра устройства? – talonmies

+0

Я также могу воспроизвести ошибку на gtx680 (вычислительная способность 3.0). Действительно, добавление cudaDeviceSynchronize заставляет код запускаться по назначению. Я полагал, что thrust :: copy имеет синхронное поведение, но на самом деле нет информации об синхронном/асинхронном поведении тяги в документации: http://thrust.github.io/doc/group__copying.html#ga24ccfaaa706a9163ec5117758fdb71b9 – Tobbey

ответ

6

Это была настоящая ошибка, и упорных developpers уже знали об этом, см https://github.com/thrust/thrust/issues/775

Используя последнюю версию 1.8.3 тяги из репозитория GitHub решить эту проблему для меня.

Смежные вопросы