Основная проблема в том, что вектор устройства spheres_dv
содержит указатели хоста.Thrust не может выполнять «глубокое копирование» или перевод указателя между адресным пространством графического процессора и центрального процессора.Поэтому, когда вы копируете spheres_h
в память GPU, вы получаете массив указателей хоста GPU.Переадресация указателей хоста на GPU недопустима - они являются указателями в неправильном адресном пространстве памяти, поэтому вы получаете эквивалентный Segfault в ядре графический процессор.
Решение будет включать в себя замену вашего parseSphere
функция с чем-то, что выполняет выделение памяти на GPU, вместо использования parseSphere
, который в настоящее время выделяет каждую новую структуру в памяти хоста.Если у вас был графический процессор Fermi (который, как вам кажется, у вас нет) и вы используете CUDA 3.2 или 4.0, то один из подходов - превратить parseSphere
в ядро.Оператор C ++ new
поддерживается в коде устройства, поэтому создание структуры будет происходить в памяти устройства.Вам нужно изменить определение Sphere
, чтобы конструктор был определен как функция __device__
, чтобы этот подход работал.
Альтернативный подход будет включать создание массива хоста, содержащего указатели устройства, а затем скопироватьэтот массив в память устройства.Вы можете увидеть пример этого в этом ответе .Обратите внимание, что, вероятно, случай, когда объявление thrust::device_vector
, содержащее thrust::device_vector
, не сработает, поэтому вам, вероятно, нужно будет создать этот массив указателей устройств, используя базовые вызовы API CUDA.
Вам следуетТакже обратите внимание, что я не упомянул операцию обратного копирования, что в равной степени сложно сделать.
Суть в том, что тяга (и контейнеры C ++ STL в этом отношении) действительно не предназначены для хранения указателей.Они предназначены для хранения значений и отвлечения косвенных указателей и прямого доступа к памяти с помощью итераторов и базовых алгоритмов, которые пользователь не должен видеть.Кроме того, проблема «глубокого копирования» является основной причиной, по которой мудрые люди на форумах NVIDIA советуют использовать несколько уровней указателей в коде графического процессора.Это сильно усложняет код, а также работает медленнее на GPU.